如何在实体框架选择查询中排除“ ThenInclude”对象中的列

时间:2019-05-29 12:22:16

标签: entity-framework select

我正在做一个复杂的实体框架选择查询,我想排除对象“ ThenIncluded”中的一个特定列。

我试图在StackOverflow中找到一个解决方案,但没有一个真正适合我的复杂查询。

以下是查询:

// topLevelId is given when we get here
await this.Context.TopLevel
                .Include(c1 => c1.Child1)
                .Include(c2 => c2.Child2)
                .Include(c3 => c3.Child3)
                .Include(c4 => c4.Child4).ThenInclude(gc1 => gc1.GrandChild1)
                .Include(c4 => c4.Child4).ThenInclude(gc2 => gc2.GrandChild2)
                .Include(c4 => c4.Child4).ThenInclude(gc3 => gc3.GrandChild3)
                .FirstAsync(tl => tl.TopLevelId == topLevelId);

我需要从中排除一列的“ ThenIncluded”对象是 GrandChild1 ,这种类型:

public partial class Document
{
    public Document()
    {
        this.MyType = new HashSet<MyType>();
    }

    public Guid DocumentId { get; set; }
    public string DocumentName { get; set; }
    public string FileName { get; set; }
    public string MimeType { get; set; }
    public byte[] Data { get; set; }

    public ICollection<MyType> MyType { get; set; }
}

我要排除的列是数据(字节数组)。

NB:在其他查询和更新中我需要该列,因此我不能忽略我的EF模型中的列。

1 个答案:

答案 0 :(得分:0)

根据消费者的需求,您可以使用.Select()告诉EF您想要提取哪些数据。这可以像您的数据模型一样是关系型的,也可以将数据从层次结构展平为更简单的结构。

例如,给定:

await this.Context.TopLevel
                .Include(c1 => c1.Child1).ThenInclude(gc1 => gc1.GrandChild1)
                .FirstAsync(tl => tl.TopLevelId == topLevelId); 

假设GrandChild1是具有字节数组的Document。

public class TopLevelViewModel
{
   public int TopLevelId { get; set; }
   public int Child1Id { get; set; }
   public string DocumentName { get; set; }
   public string FileName { get; set; }
}

await this.Context.TopLevel
    .Select(x => new TopLevelViewModel
    {
        TopLevelId = x.TopLevelId,
        Child1Id = x.Child1.Child1Id,
        DocumentName = x.Child1.Grandchild1.DocumentName,
        FileName = x.Child1.GrandChild1.FileName
    }).SingleAsync(x => x.TopLevelId = topLevelId);

如果子代表示一对多集合,则可以定义带有其相关文档详细信息的ChildViewModel:

public class TopLevelViewModel
{
   public int TopLevelId { get; set; }
   public ICollection<Child1ViewModel> Children { get; set; } = new List<Child1ViewModel>();
}
public class Child1ViewModel
{
   public int Child1Id { get; set; }
   public string DocumentName { get; set; }
   public string FileName { get; set; }
}

await this.Context.TopLevel
    .Select(x => new TopLevelViewModel
    {
        TopLevelId = x.TopLevelId,
        Children = x.Child1s.Select( c => new Child1ViewModel
        {
            Child1Id = c.Child1Id,
            DocumentName = c.Grandchild1.DocumentName,
            FileName = c.GrandChild1.FileName
        }).ToList()
    }).SingleAsync(x => x.TopLevelId = topLevelId);

您可以构建关系和数据,以根据需要进行拉回。优点在于,您只需拉回所需的数据字段即可减少有效负载大小以提高性能,利用数据库上的索引,并避免向用户透露太多有关您的数据结构的信息。