如何包含大量子实体?

时间:2015-11-20 16:21:55

标签: 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 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.cs ConfigureServices下的services.AddMvc().AddJsonOptions(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; }); 所提供的内容:

{% for resource in results %}
    <li>
        <a href="{{resource.url}}"> {{resource.url}}
                 {{resource.stats_set.values.0.avg}}</a>
<!-- truncated, the rest of the template just generates a form and 
 isn't causing any unnecessary sql -->
{% endfor %}

1 个答案:

答案 0 :(得分:0)

创建一个类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;
}

执行此操作您不必包含所有属性,它们将在序列化时自动包含在内。但是,正如@ felix-b所说,这会影响性能,因为它会为DB生成多个查询。最好使用include而不是延迟加载。