使用实体框架的动态加载,LINQ

本文关键字:加载 LINQ 动态 实体 框架 | 更新日期: 2023-09-27 18:06:24

我正在做ASP。. NET MVC项目。我正在使用EF代码优先的方法。我有三个类,它们是:

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查询。我也不确定是否继续使用急切加载或回到其他东西。

请有导师能帮我吗?

使用实体框架的动态加载,LINQ

试试这个:

var result = db.C
    .Where(c => c.B.A.A1 == 4)
    .Select(c => c.C1)
    .ToList()

你不必在这里使用急切加载(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

默认情况下EF使用延迟加载,这意味着您将不会获得,直到您请求。使用ToList()或ToArray()使EF对sql执行查询,并将这些对象放入内存实体中。如果需要,您可以执行原始sql查询,如YourDbContext.SqlQuery<T>("select * from ...")