C# using语句中的实体框架延迟加载
我很好奇,当我深入到实体框架时,我很乐意帮助我理解我在这里展示的示例中关于延迟加载的内容:C# using语句中的实体框架延迟加载,c#,entity-framework,lazy-loading,eager-loading,C#,Entity Framework,Lazy Loading,Eager Loading,我很好奇,当我深入到实体框架时,我很乐意帮助我理解我在这里展示的示例中关于延迟加载的内容: public partial class Customer { public int CustomerID { get; set; } public Nullable<int> PersonID { get; set; } public Nullable<int> StoreID { get; set; } public Nullable<in
public partial class Customer
{
public int CustomerID { get; set; }
public Nullable<int> PersonID { get; set; }
public Nullable<int> StoreID { get; set; }
public Nullable<int> TerritoryID { get; set; }
public string AccountNumber { get; set; }
public System.DateTime ModifiedDate { get; set; }
public virtual Territory Territory { get; set; }
}
public partial class Territory
{
public Territory()
{
this.Customers = new HashSet<Customer>();
}
public int TerritoryID { get; set; }
public string Name { get; set; }
public string CountryRegionCode { get; set; }
public string C_Group_ { get; set; }
public decimal SalesYTD { get; set; }
public decimal SalesLastYear { get; set; }
public virtual ICollection<Customer> Customers { get; set; }
}
public ActionResult LoadData()
{
var draw = Request.Form.GetValues("draw").FirstOrDefault();
var start = Request.Form.GetValues("start").FirstOrDefault();
var length = Request.Form.GetValues("length").FirstOrDefault();
var sortColumn = Request.Form.GetValues("columns[" + Request.Form.GetValues("order[0][column]").FirstOrDefault() + "][name]").FirstOrDefault();
var sortColumnDir = Request.Form.GetValues("order[0][dir]").FirstOrDefault();
var pageSize = length != null ? Convert.ToInt32(length) : 0;
var skip = start != null ? Convert.ToInt32(start) : 0;
int totalRecords = 0;
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
//1.
var items = dc.Customers.Select(a => a);
//2.
//var items = dc.Customers.Select(a => new
//{
// a.CustomerID,
// a.PersonID,
// a.StoreID,
// TerritoryName = a.Territory.Name,
// a.AccountNumber,
// a.ModifiedDate
//});
if (!(string.IsNullOrEmpty(sortColumn) && string.IsNullOrEmpty(sortColumnDir)))
{
items = items.OrderBy(sortColumn + " " + sortColumnDir);
}
totalRecords = items.Count();
var data = items.Skip(skip).Take(pageSize).ToList();
return Json(new { recordsFiltered = totalRecords, recordsToral = totalRecords, data = data }, JsonRequestBehavior.AllowGet);
}
}
公共部分类客户
{
public int CustomerID{get;set;}
公共可为空的PersonID{get;set;}
公共可空存储ID{get;set;}
公共可空TerritoryID{get;set;}
公共字符串AccountNumber{get;set;}
public System.DateTime ModifiedDate{get;set;}
公共虚拟区域{get;set;}
}
公共部分阶级领土
{
公共领域()
{
this.Customers=new HashSet();
}
公共int TerritoryID{get;set;}
公共字符串名称{get;set;}
公共字符串CountryRegionCode{get;set;}
公共字符串C_组{get;set;}
公共十进制SalesYTD{get;set;}
去年的公共十进制销售{get;set;}
公共虚拟ICollection客户{get;set;}
}
公共操作结果加载数据()
{
var draw=Request.Form.GetValues(“draw”).FirstOrDefault();
var start=Request.Form.GetValues(“start”).FirstOrDefault();
var length=Request.Form.GetValues(“length”).FirstOrDefault();
var sortColumn=Request.Form.GetValues(“columns[”+Request.Form.GetValues(“order[0][column]”)。FirstOrDefault()+“][name]”。FirstOrDefault();
var sortColumnDir=Request.Form.GetValues(“订单[0][dir]”)。FirstOrDefault();
var pageSize=length!=null?转换.ToInt32(长度):0;
var skip=start!=null?转换.ToInt32(start):0;
int totalRecords=0;
使用(MyDatabaseEntities dc=new MyDatabaseEntities())
{
//1.
var items=dc.Customers.Select(a=>a);
//2.
//var items=dc.Customers.Select(a=>new
//{
//a.客户ID,
//a.人格,
//a.StoreID,
//TerritoryName=a.Territory.Name,
//a.帐号,
//修改过的
//});
if(!(string.IsNullOrEmpty(sortColumn)和&string.IsNullOrEmpty(sortColumnDir)))
{
items=items.OrderBy(sortColumn+“”+sortColumnDir);
}
totalRecords=items.Count();
var data=items.Skip(Skip).Take(pageSize.ToList();
返回Json(新的{recordsFiltered=totalRecords,recordsToral=totalRecords,data=data},JsonRequestBehavior.AllowGet);
}
}
我已经编号了一些零件。在第一种情况下,正如您看到的,我选择了所有客户,延迟加载是真的,这会抛出一个错误:
ObjectContext实例已被释放,不能再用于需要连接的操作
如果我取消对第二部分的注释,它将不会出错。它们之间唯一的区别是,在第二种情况下,我选择了我需要的列,这是因为
JsonResult
(from返回Json(…)
语句)将由ASP在using
块离开后执行,它将尝试序列化Customer
对象的所有字段,并在处理dbcontext后尝试访问Territory
引用属性。我认为您不需要Select(a=>a)
在第一种情况下。还有什么是项目。这里的OrderBy
?OrderBy不使用字符串作为参数,它使用func或更常见的表达式。@DavidG我认为这是可以理解的,因为我没有编写完整的代码,我重新编译了它,您可以现在检查,但在第二种情况下,我还引用了select语句中的Territory字段,它可以工作。为什么?@www1986,是的,第二种情况下没有惰性,因为您在离开using块之前获取valueTerritoryName=a.Territory.Name
。因此,在第一种情况下,Territory
在您的操作返回(并且dbcontext被释放)后在结果执行期间被延迟评估,在第二种情况下,dbcontext在结果执行期间不存在,您已经执行了对数据库的请求(items.Count()
和items.Skip(Skip).Take(pageSize).ToList()
)您正在使用的是匿名类型,它已经获取了所有数据。谢谢,我补充说,如果您在第一种情况下(如items=dc.Customers.Include(a=>a.Territory)
)添加eager-loading,则不会失败,但是,如果在第二种情况下为延迟加载添加一些内容,它也会失败(在第二种情况下,您可以尝试在select语句中添加类似Terr=a.Territory的内容,
,因为Territory
具有导航属性Customers
它应该失败)@www1986,没有问题)是的,在第一种情况下,如果没有延迟加载,它将为Territory
返回null,因为它不是在您的查询中从db中获取的(您可以使用探查器查看在您的db上执行的查询),如果您添加,它将起作用。Include(w=>w.Territory)
。在第二个例子中,您明确地告诉您在select子句中需要Territory
,所以它是从db中获取的。你可以看到一个小的解释。