System.Data虽然不引人关注,但在.NET中,System.Data对于各种关系数据库的连接是非常重要的。System.Data也被成为ADO.NET,其前身是ActiveX Data Objects。System.Data提供了通过的框架,在她的基础上.NET数据驱动应用可以被构建。这个框架还提供了数据驱动程序应遵守的一些约定。
Connections,commands,data readers都是双继承。每个分别实现了来自于DbConnection, DbCommand,DbDataReader的基础功能。他们也实现了抽象接口IDbConnection, IDbCommand, 和IDbDataReader,这使得它们能够支持模拟场景和非传统数据源。在下文描述的基础类中都基于双继承方案。
虽然,connection strings一般被认为是字符串,但有些工具却认为它是继承自DbConnectionStringBuilder的对象。它能够处理数据库连接字符串的特定解析并帮助开发人员更好的理解特定数据库的可用设置。
在.NET中System.Data早于ORM框架出现,但是通过实现DbDataAdapter和DbCommandBuilder,它提供了生成sql的通用方法。它可以被直接使用,也能和普通数据集及类型化数据集组合使用。
如果你想找到一个抽象工厂模式的例子,你可以看下DbProviderFactory。它的自雷提供了connections, commands, command parameters, command builders, data adapters。其中包含了你需要的全部关于数据访问的需求,而不仅仅是数据库的逻辑。
接口的问题
在上文中已经提到,System.Data依赖于双继承。当我们想添加新的方法时,这将带来问题。例如,异步操作被加入到在.NET 4.5的DbCommand之中。但是却无法将他们添加到匹配的IDbCommand接口之中,因为这将是一个破坏性的改变。这意味着您不能同时使用异步操作和容易模拟的抽象接口。
微软本可以在.NET Core 1.0中重新设计抽象接口,以使得其能够与抽象类相匹配(Java通过JDBC的接口已经实现了)。然而,这却会使得.NET Framework共用源码变得困难。
如果默认接口方法能够出现在C#8.0中,在理论上,这一特征可以用来以向后兼容的方式调整接口。但是在.NET Framework中并不兼容,因为默认接口方法只是.NET Core的特征。它也不能使用较老的编译器和其他.NET语言。
DbDataReader.Get()中的字符串重载
我们对于System.Data在.NET Core 3.0之中的第一个特征是DbDataReader的Get()方法之中能够传递列名。长期以来,人们一直抱怨这个接口不能按名称引用列。这意味着你需要使用这个模式 。
reader.GetInt32(reader.GetOrdinal("columnName"))
一个明显的(对某些人来说,也是早就应该有的)简化方法是提供字符串重载。
reader.GetInt32("columnName")
这已经在Oracle's Connector/NET和MySqlConnector中实现。
处于性能考虑,该方法不会被标记为虚方法,从而允许JIT编译器轻松地内联它。也是由于上述原因,新的方法集不会添加到IDbDataReader中。
XmlDataDocument
如果你了解XmlDataDocument的历史,这似乎是一个奇怪的选择。在2010年发布的.NET 4.0之中,其已经被标记为过时的,并提出了XmlDataDocument在未来的版本中将会被删除的警告。现在使用它的原因是一些WinForms和WPF应用程序使用它,在bug报告中称,其在Apiport的各种类别中有1-7%的使用率。
DatasetExtensions
DataTableExtensions在.NET Core 3之中将不在支持。虽然它看起来只是有6个扩展方法的类,但是在不修改System.Data的情况下,我们无法构建AsDataView方法。原因相当的复杂,涉及内部方法、类型转发和.NET Standard带来的挑战。