ADO.NET

ADO.NET的前身：ADO+

1998年起，因为Web应用程序的窜起，大大改变了许多应用程序的设计方式，传统的数据库连线保存设计法无法适用于此类应用程序，这让ADO应用程序遇到了很大的瓶颈，也让微软开始思考让数据集（Resultset，在ADO中称为Recordset）能够脱机化的能力，以及能在客户端创建一个小型数据库的概念，这个概念就是ADO.NET中脱机型数据模型（disconnected data model）的基础，而在ADO的使用情形来看，数据库连线以及资源耗用的情形较严重（像是Server-side cursor或是Recordset.Open会保持连线状态），在ADO.NET中也改良了这些对象，构成了能够减少数据库连线和资源使用量的功能。XML的使用也是这个版本的重要发展之一。
2000年，微软的Microsoft .NET项目开始成形，许多的微软产品都冠上.NET的标签，ADO+也不例外，改名为ADO.NET，并包装到.NET Framework类库中，成为.NET平台中唯一的数据访问组件。

架构

ADO.NET由连线数据源（connected data source）以及脱机数据模型（disconnected data model）两个部分构成，这两个部分是相辅相成的。

XML的集成

XML在ADO.NET中扮演了相当重要的地位，DataSet和DataTable都可以转换成XML或和XML之间交换数据，在DataTable的内部数据的变更记录，可以被输出到一个XML的格式，用来识别变更的情形，这个格式称为DiffGram，而且它可以直接读入DataTable之中（使用DataTable.ReadXml（）并用XmlReadMode.DiffGram当参数）。一个典型的DiffGram如下：
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
  <CustomerDataSet>
    <Customers diffgr:id="Customers1" msdata:rowOrder="0" diffgr:hasChanges="modified">
      <CustomerID>ALFKI</CustomerID>
      <CompanyName>New Company</CompanyName>
    </Customers>
    <Customers diffgr:id="Customers2" msdata:rowOrder="1" diffgram:hasErrors="true">
      <CustomerID>ANATR</CustomerID>
      <CompanyName>Ana Trujillo Emparedados y Helados</CompanyName>
    </Customers>
    <Customers diffgr:id="Customers3" msdata:rowOrder="2">
      <CustomerID>ANTON</CustomerID>
      <CompanyName>Antonio Moreno Taquera</CompanyName>
    </Customers>
    <Customers diffgr:id="Customers4" msdata:rowOrder="3">
      <CustomerID>AROUT</CustomerID>
      <CompanyName>Around the Horn</CompanyName>
    </Customers>
  </CustomerDataSet>
  <diffgr:before>
    <Customers diffgr:id="Customers1" msdata:rowOrder="0">
      <CustomerID>ALFKI</CustomerID>
      <CompanyName>Alfreds Futterkiste</CompanyName>
    </Customers>
  </diffgr:before>
  <diffgr:errors>
    <Customers diffgr:id="Customers2" diffgr:Error="An optimistic concurrency violation has occurred for this row."/>
  </diffgr:errors></diffgr:diffgram>
DataSet与DataTable也支持直接读入XML Schema创建结构的能力，以及自行依XML的内容推断（inference）其结构的能力，下列代码为由XML推断结构的程序：
DataSet dataSet = new DataSet();dataSet.InferXmlSchema（"input_od.xml", new string[] "urn:schemas-microsoft-com:officedata"）;
DataSet和DataTable可以使用XmlDataDocument类别和XML DOM集成在一起，XmlDataDocument的角色就像一个桥接接口，并且作为DataSet和DataTable可使用XPath与XML DOM方式访问的方法。下列代码即为使用XmlDataDocument和数据库中数据转换为XSLT输出的示例：
// Assumes connection is a valid SqlConnection.connection.Open();DataSet custDS = new DataSet("CustomerDataSet");SqlDataAdapter customerAdapter = new SqlDataAdapter(
  "SELECT * FROM Customers", connection);customerAdapter.Fill(custDS, "Customers");SqlDataAdapter orderAdapter = new SqlDataAdapter(
  "SELECT * FROM Orders", connection);orderAdapter.Fill(custDS, "Orders");connection.Close();custDS.Relations.Add("CustOrders",
  custDS.Tables["Customers"].Columns["CustomerID"]，
                     custDS.Tables["Orders"].Columns["CustomerID"]).Nested = true;XmlDataDocument xmlDoc = new XmlDataDocument (custDS); 

XslTransform xslTran = new XslTransform();xslTran.Load（"transform.xsl"）;XmlTextWriter writer = new XmlTextWriter("xslt_output.html", 
  System.Text.Encoding.UTF8);xslTran.Transform(xmlDoc, null, writer);writer.Close();
在.NET Framework中，DataSet被分为两类，一种是不会强制使用特别类型的DataSet，称为Untyped DataSet，使用上较方便，但没有强制的类型限制，另一种则是Typed DataSet，会强制类型，并且是由自定义的XML Schema所产生，Untyped DataSet则没有XML Schema，由创建时的结构来决定，Typed DataSet可以用Visual Studio，或者是SDK工具中的xsd.exe来产生。
xsd.exe /d /l:CS XSDSchemaFileName.xsd /eld /n:XSDSchema.Namespace
产生出来的Typed DataSet会自动将字段设置成属性，让开发人员的访问更方便（这个功能在TableAdapter相当常见）。
CustomerDataSet customers = new CustomerDataSet();SqlDataAdapter adapter = new SqlDataAdapter(
  "SELECT * FROM dbo.Customers;",
  "Data Source=(local);Integrated " +
  "Security=SSPI;Initial Catalog=Northwind");adapter.Fill(customers, "Customers");foreach(CustomerDataSet.CustomersRow customerRow in customers.Customers)
  Console.WriteLine(customerRow.CustomerID);

Visual Studio的支持

ADO.NET和Visual Studio开发工具几乎已经是无缝的集成了，开发人员可以利用Visual Studio来创建强类型（strong-typed）的DataSet，到了Visual Studio 2005时更能够在Windows Forms应用程序中使用TableAdapter（Typed DataSet和DataAdapter集成的产物）来开发应用程序（不会再看到DataAdapter，但使用上差不多）。Visual Studio在创建Typed DataSet时有提供可视化接口的支持，以及数据库配置向导（Database Configuration Wizard）来让开发人员以简单的设置方式来创建DataSet，部分开发人员也将TableAdapter和ASP.NET应用程序的ObjectDataSource控件并用，亦得到不错的效果。
在.NET Framework 3.5中，微软特别为了DataSet和DataTable创建了LINQ Provider（称为LINQ to DataSet或LINQ to ADO.NET），让LINQ可以在DataSet或DataTable上使用，可以让原本在DataSet上的投资（代码）得以继续使用并享有LINQ的便利性。

ADO.NET和ADO的差异

对于ADO的开发人员来说，最明显的变化在于以往ADO中的Recordset消失了，并且明确的分开为连线型的DataReader以及脱机型的DataSet与DataTable，并且发展支持脱机型数据源的浏览工具DataView，这样的改变，让习惯使用ADO的VB/ASP开发人员会有某种程度的不习惯，同时让ADO.NET的学习会较ADO有较些许的复杂性，因此有部分新入门或是VB 6.0/ASP开发人员会在学习.NET Framework或是使用VB.NET开发应用程序时，在.NET Framework中使用ADO来连接数据源。但在.NET Framework应用程序使用ADO的话，.NET Framework会因为要多一层ADO的COM与VB.NET使用的.NET之间的数据转换，会让应用程序性能有少部分的损耗。
下述示例，用ADO读取一个数据库中的表格，然后转为ADO.Net的数据，最后绑定到DataGridView控件中去显示：
        Dim cn As ADODB.Connection
        Dim rs As ADODB.Recordset
        cn = New ADODB.Connection
        rs = New ADODB.Recordset
        cn.Provider = "Microsoft.ACE.OLEDB.12.0;"
        cn.ConnectionString = "D:\\budget2016.accdb;"
        cn.Open()

        'check whether the serial num exists in table cutter
        Dim sSQL As String = "SELECT * FROM tPassword" 
        rs.CursorLocation = ADODB.CursorLocationEnum.adUseClient
        rs.Open(sSQL, cn, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockReadOnly,_ 
                 ADODB.CommandTypeEnum.adCmdText)

        Dim da As New System.Data.OleDb.OleDbDataAdapter()
        Dim ds As New DataSet()
        da.Fill(ds, rs, "tPassword")

        'rs.Close()  'Cannot close 
        rs.ActiveConnection = Nothing
        cn.Close()
        rs = Nothing
        cn = Nothing

        DataGridView1.DataSource = (ds.Tables("tPassword"))
ADO的RecordSet，相当于在客户机或服务器的一个逻辑上的数据表格，用户可以通过cursor来定位/读写当前行，但不能重新对这些行重新排序，也不能对客户机上的多个RecordSet数据执行跨表的连接（join）查询。ADO.Net针对上述缺点，在客户机上实现了DataTable与DataSet，这是客户机内存中的一套（多个）数据表格，可以对其执行各种单表或多表的查询、修改、删除操作，既可以使用SQL语句，也可以使用LINQ子语言。
ADO与ADO.Net的共同点，在其内部都是使用SQL语句来对后台数据库操作。
内在实现上，ADO是基于COM技术，因此变体类型（Variant）无处不在，这是一种通用、万能类型；而ADO.Net是强类型的，并很好地支持数据库元数据与XML功能。

ADO.NET的进化

随着网络应用程序的进化，ADO.NET也随之做了许多的改变，但不变的是，ADO.NET的基础提供了强固的发展支持，这些进化的技术都是植基于ADO.NET的核心组件而来。
长久以来，程序员和数据库总是保持着一种微妙的关系，在商用应用程序中，数据库一定是不可或缺的组件，这让程序员一定要为了连接与访问数据库而去学习SQL指令，因此在信息业中有很多人都在研究如何将程序设计模型和数据库集成在一起，对象关系对应（Object-Relational Mapping）的技术就是由此而生，像Hibernate或NHibernate都是这个技术下的产物，而微软虽然有了ADO.NET这个数据访问的利器，但却没有像NHibernate这样的对象对应工具，因此微软在.NET Framework 2.0发展时期，就提出了一个ObjectSpace的概念，ObjectSpace可以让应用程序可以用完全对象化的方法连接与访问数据库，其技术概念与NHibernate相当类似，然而ObjectSpace项目相当大，在.NET Framework 2.0完成时仍无法全部完成，因此微软将ObjectSpace纳入下一版本的.NET Framework中，并且再加上一个设计的工具（Designer），构成了现在的ADO.NET Entity Framework。
Entity Framework利用了抽象化数据结构的方式，将每个数据库对象都转换成应用程序对象（entity），而数据字段都转换为属性（property），关系则转换为结合属性（association），让数据库的E/R模型完全的转成对象模型，如此让程序员能用最熟悉的编程语言来调用访问。而在抽象化的结构之下，则是高度集成与对应结构的概念层、对应层和存储层，以及支持Entity Framework的数据提供者（provider），让数据访问的工作得以顺利与完整的进行。
以往在发展像是AJAX应用程序时，伺服端总是需要设计一个HTTP接口端口（end point），通常都会使用Web Service来实现，但是随着Mashup应用程序的成长，若每次都要为一份（或一组）数据撰写Web Service或HTTP end point的话，对开发人员也是不小的负担，而且Web Service只支持XML/SOAP的数据格式，无法兼容于Mashup应用程序常用的JSON数据格式，微软也发现未来的Silverlight应用程序也是会面临到相同问题。
当时刚好微软的ADO.NET Entity Framework也正在开发中，它的EDM能力刚好可以提供给WCF数据访问的能力，因此微软特别以ADO.NET Entity Framework为基础，开发一个专门提供HTTP端点数据服务的数据供应层，即为WCF Data Services。