我正在做一个复杂的实体框架选择查询,我想排除对象“ 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模型中的列。
答案 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);
您可以构建关系和数据,以根据需要进行拉回。优点在于,您只需拉回所需的数据字段即可减少有效负载大小以提高性能,利用数据库上的索引,并避免向用户透露太多有关您的数据结构的信息。