我正在研究ASP.NET MVC项目。我正在使用EF代码优先方法。我有3个班级,分别是:
public class A
{
public int AID {get;set;}
public string A1 {get;set}
public string A2 {get;set}
public virtual List<B> Bs {get;set;}
}
public class B
{
public int BID {get;set;}
public string B1 {get;set}
public string B2 {get;set}
public AID {get;set}
public virtual A A {get;set}
public virtual List<C> Cs {get;set;}
}
public class C
{
public int CID {get;set;}
public string C1 {get;set}
public string C2 {get;set}
public BID {get;set}
public virtual B B {get;set}
}
我想基于B类选择C类的C1属性,其中A1 = 4。 我尝试使用:
var result = db.C.select(x=>x.C1).Include(x=>B).where(x=>x.A.equals(4))
我很困惑,不知道如何执行linq查询。此外,我不确定是继续使用预先加载还是继续使用其他内容。
请任何大师请帮帮我吗?
答案 0 :(得分:3)
试试这个:
var result = db.C
.Where(c => c.B.A.A1 == 4)
.Select(c => c.C1)
.ToList()
您不必在此处使用Eager loading(Include
),因为结果中不包含任何嵌套实体。
预先加载用于解决SELECT N + 1问题。当您检索父实体并想要遍历其子项时,会出现此问题。这导致向数据库发出N + 1个请求。
以下是代码示例:
没有预先加载
var carList = db.Cars.ToList(); //this will create one request to the database to retrieve all cars
foreach(var car in carList)
{
foreach(var wheel in car.Wheels) //this line will create another request to the database to retrieve wheels for specific car
}
Console.Write("Car = {0}, Wheel = {1}", car, wheel);
}
}
//Total requests: 1 to get car list + N requests to retrieve wheels where N - total number of cars
急切加载
var carList = db.Cars.Include(x => x.Wheels).ToList(); //this will create one request to the database to retrieve all cars together with information about wheels
foreach(var car in carList)
{
foreach(var wheel in car.Wheels) //this line won't create extra request to the database because this data has been already loaded using eager loading
}
Console.Write("Car = {0}, Wheel = {1}", car, wheel);
}
}
//Total requests: 1 to get car list with all wheel information
答案 1 :(得分:0)
默认情况下,EF使用延迟加载,这意味着在你要求之前你不会得到它。使用ToList()或ToArray()使EF对sql执行查询并将这些对象放入内存中实体。
如果需要,您可以执行原始SQL查询,如YourDbContext.SqlQuery<T>("select * from ...")