Entity framework 如何包含大量子实体?
我在玩EF7,只是想知道是否有更快的方法来包含实体中的所有子实体 我的课程包括:Entity framework 如何包含大量子实体?,entity-framework,entity-framework-core,Entity Framework,Entity Framework Core,我在玩EF7,只是想知道是否有更快的方法来包含实体中的所有子实体 我的课程包括: public class A { public int Id { get; set; } public int Name { get; set; } public virtual B B { get; set; } public virtual C B { get; set; } } public class B { public int Id { get; set; }
public class A
{
public int Id { get; set; }
public int Name { get; set; }
public virtual B B { get; set; }
public virtual C B { get; set; }
}
public class B
{
public int Id { get; set; }
public int Name { get; set; }
public virtual BA BA { get; set; }
public virtual BB BB { get; set; }
}
public class C
{
public int Id { get; set; }
public int Name { get; set; }
public virtual CA CA { get; set; }
public virtual CB CB { get; set; }
public virtual CC CC { get; set; }
}
我现在就是这样做的,包括所有的子实体
A test = _dbContext.As.Where(a => a.Id == id)
.Include(a => a.B)
.ThenInclude(b => b.BA)
.Include(a => a.B)
.ThenInclude(b => b.BB)
.Include(a => a.C)
.ThenInclude(c => c.CA)
.Include(a => a.C)
.ThenInclude(c => c.CB)
.Include(a => a.C)
.ThenInclude(c => c.CC)
这对于一个小的层次结构是很好的,但是如果实体很大,就会有很多重复
我不想关闭延迟加载
以下是我将查询传递到前端的方式:
[Route("api/Test/{id}")]
[HttpGet]
public A Get(int id)
{
A test = _dbContext.As.Where(a => a.Id == id)
.Include(a => a.B)
.ThenInclude(b => b.BA)
.Include(a => a.B)
.ThenInclude(b => b.BB)
.Include(a => a.C)
.ThenInclude(c => c.CA)
.Include(a => a.C)
.ThenInclude(c => c.CB)
.Include(a => a.C)
.ThenInclude(c => c.CC)
return test;
}
这是我在ConfigureServices
下的Startup.cs
中看到的内容:
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
创建一个类
AViewModel
,以表示要发送到视图的数据,然后修改方法,如下所示:
[Route("api/Test/{id}")]
[HttpGet]
public A Get(int id)
{
List<AViewModel> test = _dbContext.As.Where(a => a.Id == id)
.Select(i => new AViewModel
{
a = B.BA,
b = B.BB,
c = C.CA,
d = C.CB,
e = C.CE
}).ToList();
return test;
}
[路由(“api/Test/{id}”)]
[HttpGet]
公共A Get(int id)
{
List test=_dbContext.As.Where(a=>a.Id==Id)
.选择(i=>new AViewModel
{
a=B.BA,
b=b.BB,
c=c.CA,
d=C.CB,
e=C.CE
}).ToList();
回归试验;
}
执行此操作时,您不必包含所有属性,它们将在序列化时自动包含。然而,正如@felix-b所说的,这将影响性能,因为它将向数据库生成多个查询。最好使用include而不是lazy-loading。等等,如果使用lazy-loading,则不必包含所有实体;如果我想将它们发送到web前端,它们将在访问时自动包含。这不是真的,问题是您没有迭代属性。。。您必须迭代属性(通常转换其他类或匿名对象中所需的所有属性)。提供将查询发送到前端的代码,我将演示如何执行此操作谢谢Fabio,问题edited@FabioLuz依赖于延迟加载可能会影响性能,因为对尚未加载的属性的每次访问都会导致对DB的额外查询。从action方法返回的可查询对象将在响应序列化过程中枚举,并且序列化程序将访问返回实体的所有属性,从而导致对DB的大量查询,从而显著降低响应速度(称为选择N+1问题)。在这种情况下,Include应该优先于延迟加载,因为只有一个带有JOIN的“大”查询将在数据库上执行。