Поделиться через


ADO.NET и LINQ to SQL

LINQ to SQL является частью семейства технологий ADO.NET. Он основан на службах, предоставленных моделью поставщика ADO.NET. Поэтому код LINQ to SQL можно сочетать с существующими приложениями ADO.NET и выполнять переход с текущих решений ADO.NET на LINQ to SQL. На следующем рисунке показано общее представление связи.

LINQ в SQL и ADO.NET

Соединения

При создании DataContext LINQ to SQL можно использовать существующее подключение ADO.NET. Оно будет использоваться для выполнения всех операций относительно DataContext (включая запросы). Если подключение уже открыто, по завершении работы с ним LINQ to SQL оставит его без изменений.

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()
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();

Для постоянного доступа к подключению и его закрытия можно использовать свойство Connection, как показано в следующем коде.

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

Транзакции

Когда приложение уже инициировало транзакцию и в нее требуется включить DataContext, его можно добавить в собственную транзакцию базы данных.

Рекомендуемым методом выполнения транзакций с .NET Framework является использование объекта TransactionScope. Благодаря этому способу можно выполнить распределенные транзакции, работающие в базах данных и других находящихся в памяти диспетчерах ресурсов. Для запуска транзакций требуется незначительное количество ресурсов. Они преобразуются в распределенные транзакции только при наличии в области действия транзакции нескольких подключений.

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

Этот способ не подходит для всех баз данных. Например, подключение SqlClient не может повысить уровень системных транзакций, если используется на сервере SQL Server 2000. Наоборот, оно автоматически включается в полную, распределенную транзакцию при каждом обнаружении используемой области действия транзакции.

Прямые команды SQL

Иногда могут возникать ситуации, когда возможность DataContext осуществлять запросы или отправлять изменения будет недостаточной для выполнения специализированной задачи. В подобных случаях, чтобы запустить команды SQL в базе данных и преобразовать результаты запроса в объекты, можно использовать метод ExecuteQuery.

Например, предположим, что данные для класса Customer распределены по двум таблицам (customer1 и customer2). Следующий запрос возвращает последовательность двух объектов Customer.

    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")
            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"
);

Если имена столбцов в табличных результатах соответствуют свойствам столбцов класса сущностей, LINQ to SQL создает объекты вне запроса SQL.

Параметры

Метод ExecuteQuery допускает использование параметров. В следующем коде выполняется параметризованный запрос.

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

Параметры записываются в тексте запроса с использованием той же нотации с фигурными скобками, что и в методах Console.WriteLine() и String.Format().Метод String.Format() принимает указанную строку запроса и заменяет параметры в фигурных скобках на автоматически созданные имена, такие как @p0, @p1…, @p(n).

См. также

Задачи

Как повторно использовать соединение между командой ADO.NET и DataContext (LINQ to SQL)

Другие ресурсы

Дополнительные сведения (LINQ to SQL)