ADO.NET 和 LINQ to SQL

LINQ to SQL 是 ADO.NET 技术系列的一部分。 它基于 ADO.NET 提供程序模型提供的服务。 因此,可以将 LINQ to SQL 代码与现有 ADO.NET 应用程序混合使用,并将当前 ADO.NET 解决方案迁移到 LINQ to SQL。 下图提供了关系的高级视图。

LINQ to SQL 和 ADO.NET

连接

创建 LINQ to SQL DataContext时,可以提供现有的 ADO.NET 连接。 针对 DataContext(包括查询)的所有操作都使用此提供的连接。 如果连接已打开,则当你完成使用时,LINQ to SQL 会保持连接不变。

string connString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=c:\northwind.mdf;
    Integrated Security=True; Connect Timeout=30; User Instance=True";
SqlConnection nwindConn = new SqlConnection(connString);
nwindConn.Open();

Northwnd interop_db = new Northwnd(nwindConn);

SqlTransaction nwindTxn = nwindConn.BeginTransaction();

try
{
    SqlCommand cmd = new SqlCommand(
        "UPDATE Products SET QuantityPerUnit = 'single item' WHERE ProductID = 3");
    cmd.Connection = nwindConn;
    cmd.Transaction = nwindTxn;
    cmd.ExecuteNonQuery();

    interop_db.Transaction = nwindTxn;

    Product prod1 = interop_db.Products
        .First(p => p.ProductID == 4);
    Product prod2 = interop_db.Products
        .First(p => p.ProductID == 5);
    prod1.UnitsInStock -= 3;
    prod2.UnitsInStock -= 5;

    interop_db.SubmitChanges();

    nwindTxn.Commit();
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
    Console.WriteLine("Error submitting changes... all changes rolled back.");
}

nwindConn.Close();
Dim conString = "Data Source=.\SQLEXPRESS;AttachDbFilename=c:\northwind.mdf; Integrated Security=True;Connect Timeout=30;User Instance=True"
Dim northwindCon = New SqlConnection(conString)
northwindCon.Open()

Dim db = New Northwnd("...")
Dim northwindTransaction = northwindCon.BeginTransaction()

Try
    Dim cmd = New SqlCommand( _
            "UPDATE Products SET QuantityPerUnit = 'single item' " & _
            "WHERE ProductID = 3")
    cmd.Connection = northwindCon
    cmd.Transaction = northwindTransaction
    cmd.ExecuteNonQuery()

    db.Transaction = northwindTransaction

    Dim prod1 = (From prod In db.Products _
                 Where prod.ProductID = 4).First
    Dim prod2 = (From prod In db.Products _
                 Where prod.ProductID = 5).First
    prod1.UnitsInStock -= 3
    prod2.UnitsInStock -= 5

    db.SubmitChanges()

    northwindTransaction.Commit()

Catch e As Exception

    Console.WriteLine(e.Message)
    Console.WriteLine("Error submitting changes... " & _
"all changes rolled back.")
End Try

northwindCon.Close()

始终可以使用该 Connection 属性访问连接并自行关闭,如以下代码所示:

db.Connection.Close();
db.Connection.Close()

交易

当你的应用程序已经启动了你自己的数据库事务并且你希望你的 DataContext 包含在内时,你可以向你的 DataContext 提供此事务。

使用 .NET Framework 执行事务的首选方法是使用对象 TransactionScope 。 通过使用此方法,可以跨数据库和其他内存驻留资源管理器进行分布式事务。 事务范围几乎不需要资源就可以启动。 仅当事务范围内有多个连接时,它们才会提升为分布式事务。

using (TransactionScope ts = new TransactionScope())
{
    db.SubmitChanges();
    ts.Complete();
}
Using ts As New TransactionScope()
    db.SubmitChanges()
    ts.Complete()
End Using

不能对所有数据库使用此方法。 例如,SqlClient 连接如果对 SQL Server 2000 服务器有效,则无法提升系统事务。 它采取的方法是,只要它发现有使用事务范围的情况,它就会自动向完整的分布式事务登记。

直接 SQL 命令

有时,你可能会遇到 DataContext 在查询或提交更改时的能力不足以执行特定任务的情况。 在这些情况下,可以使用 ExecuteQuery 该方法向数据库发出 SQL 命令并将查询结果转换为对象。

例如,假设该类的数据 Customer 分布在两个表(customer1 和 customer2) 上。 以下查询返回一系列 Customer 对象:

            IEnumerable<Customer> results = db.ExecuteQuery<Customer>(
    @"select c1.custid as CustomerID, c2.custName as ContactName
        from customer1 as c1, customer2 as c2
        where c1.custid = c2.custid"
);
    Dim results As IEnumerable(Of Customer) = _
db.ExecuteQuery(Of Customer)( _
"SELECT [c1].custID as CustomerID," & _
    "[c2].custName as ContactName" & _
    "FROM customer1 AS [c1], customer2 as [c2]" & _
    "WHERE [c1].custid = [c2].custid")

只要表格结果中的列名称与实体类的列属性匹配,LINQ to SQL 会根据任何 SQL 查询创建对象。

参数

该方法 ExecuteQuery 接受参数。 以下代码执行参数化查询:

            IEnumerable<Customer> results = db.ExecuteQuery<Customer>(
    "select contactname from customers where city = {0}",
    "London"
);
    Dim results As IEnumerable(Of Customer) = _
db.ExecuteQuery(Of Customer)( _
    "SELECT contactname FROM customers WHERE city = {0}, 'London'")
End Sub

注释

参数在查询文本中通过使用与Console.WriteLine()String.Format()相同的花括号表示法来表示。 String.Format() 采用提供的查询字符串,并将大括号参数替换为生成的参数名称,例如 @p0@p1 ..., @p(n)

另请参阅