Так можно ли просто изменить БД и быть почти независимым от БД в классическом ADO.NET?
Конечно, вы можете, но чтобы иметь возможность сделать это, мы должны развенчать это утверждение.
Кажется, что это волшебная пилюля, однако все утверждения ADO.NET жестко закодированы.
Это не побочный продукт ADO.NET - это побочный продукт вашей архитектуры. Вы создаете SQL-запросы не в том месте. Вам нужны конкретные, специфичные для поставщика модели, которые могут создавать заявления, которые отличаются между поставщиками. Это не так плохо, как кажется - большинство заявлений могут быть автоматически сгенерированы с использованием отражения - это просто особые случаи.
Например, скажем, у меня была модель так:
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}
и давайте говорить, что я хотел, чтобы создать SELECT
заявление из этого.Ну, я буду первым нужна пара атрибутов, чтобы сказать мне, что собственность является PK и какие свойства полей данных:
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
internal sealed class DataFieldAttribute : Attribute
{
public DataFieldAttribute()
{
}
}
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
sealed class PrimaryKeyAttribute : Attribute
{
public PrimaryKeyAttribute()
{
}
}
и теперь мне нужно, чтобы украсить этот класс:
public class Employee
{
[PrimaryKey]
public int ID { get; set; }
[DataField]
public string Name { get; set; }
[DataField]
public DateTime DateOfBirth { get; set; }
}
и теперь я просто нужен простой процесс, чтобы создать SELECT
заявления, поэтому сначала давайте создадим базовую модель данных класса:
public abstract class DataModelBase
{
protected string _primaryKeyField;
protected List<string> _props = new List<string>();
public DataModelBase()
{
PropertyInfo pkProp = this.GetType().GetProperties().Where(p => p.GetCustomAttributes(typeof(PrimaryKeyAttribute), false).Length > 0).FirstOrDefault();
if (pkProp != null)
{
_primaryKeyField = pkProp.Name;
}
foreach (PropertyInfo prop in this.GetType().GetProperties().Where(p => p.GetCustomAttributes(typeof(DataFieldAttribute), false).Length > 0))
{
_props.Add(prop.Name);
}
}
public virtual string TableName { get { return this.GetType().Name; } }
public virtual string InsertStatement
{
get
{
return string.Format("INSERT INTO [{0}] ({1}) VALUES ({2})",
this.TableName,
GetDelimitedSafeFieldList(", "),
GetDelimitedSafeParamList(", "));
}
}
public virtual string UpdateStatement
{
get
{
return string.Format("UPDATE [{0}] SET {1} WHERE [{2}] = @{2}",
this.TableName,
GetDelimitedSafeSetList(", "),
_primaryKeyField);
}
}
public virtual string DeleteStatement
{
get
{
return string.Format("DELETE [{0}] WHERE [{1}] = @{1}",
this.TableName,
_primaryKeyField);
}
}
public virtual string SelectStatement
{
get
{
return string.Format("SELECT [{0}], {1} FROM [{2}]",
_primaryKeyField,
GetDelimitedSafeFieldList(", "),
this.TableName);
}
}
protected string GetDelimitedSafeParamList(string delimiter)
{
return string.Join(delimiter, _props.Select(k => string.Format("@{0}", k)));
}
protected string GetDelimitedSafeFieldList(string delimiter)
{
return string.Join(delimiter, _props.Select(k => string.Format("[{0}]", k)));
}
protected string GetDelimitedSafeSetList(string delimiter)
{
return string.Join(delimiter, _props.Select(k => string.Format("[{0}] = @{0}", k)));
}
}
и теперь давайте наследовать от этой модели данных:
public class Employee : DataModelBase
и стрела, теперь я могу получить эти заявления в любое время, когда они мне нужны, и эти заявления работают для любого конкретного поставщика прямо сейчас.
И тогда я буду использовать Dapper to get the data, потому что он использует интерфейс IDbConnection
как то, что вам нужно и это смешно быстро - и там вы идете - поставщик независимого решения, которое было бы легко расширить, чтобы построить версию Oracle в Employee
, если необходимо.
Эта структура имеет внутренние независимых операторов языка, который преобразуется в выбраной DB statesment, который выглядит, как поистине волшебной таблетки
Конечно, это может выглядеть как волшебную таблетку, но это действительно проклятие в много способов. У вас нет гибкости (по крайней мере, это непросто) создавать инструкции, оптимизированные для ваших нужд, для поддержки больших транзакций и баз данных томов. Вы действительно подчиняетесь хозяину здесь. .NET Entity Framework строит эти инструкции для вас, и я даже не могу подсчитать, сколько вопросов по StackOverflow было выполнено, как я могу изменить SQL, создаваемый этим оператором LINQ, используя платформу .NET Entity Framework.
Как мы можем добавить метод создания таблицы здесь или сгенерировать сценарий создания таблицы с помощью Poco класса? – ashy