[英]What is the best LINQ-to-SQL strategy for disposing of DataContext within methods?
我知道,当从LINQ-to-SQL类获取数据时,最好使用using
块,如下所示。
但是,当我这样做时,我只能访问orders
的较浅属性(例如Order.OrderId
),而不能访问较深的属性(例如Customer.CustomerName
),因为它们似乎已在此时处置。
我可以取出我的using
块,该块允许我访问客户,但是这不会释放资源。
最佳做法是什么?
using System;
using System.Collections.Generic;
using System.Linq;
using TestExtn2343.Models;
namespace TestExtn2343
{
class Program
{
public static void Main(string[] args)
{
var orders = GetOrders(10, 10);
orders.ForEach(x =>
{
Customer customer = x.Customer;
if (customer != null)
{
//SUCCEEDS:
Console.WriteLine("{0}, {1}", x.OrderID);
//FAILS: "
Console.WriteLine("{0}, {1}", x.OrderID, x.Customer.ContactName.ToString());
}
});
Console.ReadLine();
}
public static List<Order> GetOrders(int skip, int take)
{
using (MainDataContext db = new MainDataContext())
{
List<Order> orders = (from order in db.Orders
select order).Skip(skip).Take(take).ToList();
return orders;
}
}
}
}
谢谢亚当,根据您的建议,我的代码可以这样工作:
public static void Main(string[] args)
{
using (MainDataContext db = new MainDataContext())
{
GetOrders(db, 10, 10).ForEach(x => Console.WriteLine("{0}, {1}", x.OrderID, x.Customer.ContactName.ToString()));
}
Console.ReadLine();
}
public static List<Order> GetOrders(MainDataContext db, int skip, int take)
{
List<Order> orders = (from order in db.Orders
select order).Skip(skip).Take(take).ToList();
return orders;
}
无法访问对象的更深属性,因为LINQ-to-SQL使用延迟加载 (即,它会根据需要自动检索那些记录,因此,当您第一次访问它们时,它将执行数据库操作)。 因为DataContext
已处置,所以它无法执行必要的数据库操作。 这样的属性可能会“急切地”加载(意味着在初次检索时),但是您必须预先了解所有这些属性。
通常,您的DataContext
应该在您的工作单元内有效 ,因此在这里看来您需要在此方法之外声明您的DataContext
并将其传入(或声明为您在DataContext
上的扩展方法)。
这是有关DataContext
生命周期管理的不错的博客文章 。
如果您知道要获得客户的事实,则可以在DataLoadOptions中指定它,它将连接请求以热切地加载它们,而不是延迟加载它们。
例:
var dlo = new DataLoadOptions();
dlo.LoadWith<Order>(o => o.Customer);
context.DataLoadOptions = dlo;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.