【发布时间】:2015-11-20 16:21:54
【问题描述】:
我正在使用 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 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;
}
这是我在Startup.csConfigureServices下的内容:
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
【问题讨论】:
-
等等,如果您使用延迟加载,则不必包含所有实体;访问时会自动包含它们。
-
如果我想将它们发送到网络前端,则不是。
-
这不是真的,问题是你没有迭代属性......你必须迭代属性(通常在另一个类或匿名对象中转换你需要的所有内容)。提供将查询发送到前端的代码,我会告诉你如何做到这一点
-
感谢法比奥,问题已编辑
-
@Fabio Luz,依赖延迟加载会影响性能,因为对尚未加载的属性的每次访问都会导致对数据库的额外查询。响应序列化时会枚举action方法返回的可查询对象,返回实体的所有属性都会被序列化器访问,导致对DB的大量查询,显着减慢响应(称为SELECT N+1问题) )。在这种情况下,应优先使用包含而不是延迟加载,因为只有一个带有 JOIN 的“大”查询会在数据库上执行。
标签: entity-framework entity-framework-core