C# 在EF6 Include中仅包含部分实体

C# 在EF6 Include中仅包含部分实体,c#,linq,entity-framework-6,C#,Linq,Entity Framework 6,我有一个模型,其中包括可以具有Id、名称和二进制数据属性的附件的穿孔 如果我这样做: var result = context.PunchSet .Where(p => p.PunchType == punchType && p.Project.Id == projectId) .Include(c => c.Contractor) .Include(c => c.ClearedBy) .Include(c => c.Created

我有一个模型,其中包括可以具有Id、名称和二进制数据属性的附件的穿孔

如果我这样做:

var result = context.PunchSet
   .Where(p => p.PunchType == punchType && p.Project.Id == projectId)
   .Include(c => c.Contractor)
   .Include(c => c.ClearedBy)
   .Include(c => c.CreatedBy)
   .Include(a => a.Attachments)
查询速度和molassis一样慢,因为附件可以多也可以大。在本例中,我只需要附件的Id和名称。所以我试着:

var result = context.PunchSet
    .Where(p => p.PunchType == punchType && p.Project.Id == projectId)
    .Include(c => c.Contractor)
    .Include(c => c.ClearedBy)
    .Include(c => c.CreatedBy)
    .Include(a => a.Attachments.Select(a2 => new Attachment() { Id=a2.Id, Name=a2.Name} );
但最终会出现以下错误:

包含路径表达式必须引用导航属性 在类型上定义。使用虚线路径进行参考导航 属性和集合导航的选择运算符 财产。参数名称:路径


我不知道这意味着什么,我已经被困了好几个小时了。如何在结果中包含部分实体?也就是说,不要读取二进制数据。

您可以尝试在单个查询中选择所有所需的属性,然后在内存中将它们连接在一起

db.PunchSet
    .Include(x => x.Contractor)
    // ... other includes of complete objects
    // then select properties for partial include
    .Select(x => new { obj = x, att = x.Attachments.Select(a => new { a.Id, a.Name }) })
    // end of database query context
    .AsEnumerable()
    // join the results in memory
    .Select(x =>
    {
        x.obj.Attachments = x.att.Select(a => new Attachment() { Id = a.Id, Name = a.Name }).ToList();
        return x.obj;
    });

您可以按如下所示进行尝试

var result =  from p in context.PunchSet 
               where (p.PunchType == punchType && p.Project.Id == projectId) 
               select new { 
                           p,  
                           Contractor=p.Contractor,
                           ClearedBy =p.ClearedBy,
                           CreatedBy=p.CreatedBy,

                           Attachments= from a in p.Attachments
                                        select new {
                                                     Id=  a.Id,
                                                     Name =a.Name, 
                                                   },

             };

var result2 = result.AsEnumerable() 
                    .Select(c => c.p);
之后,您可以根据需要进行迭代:)


你不能部分包括。但是,如果您只想阅读而不想更新,您可以省略包含中的附件并单独加载它们。我如何在同一查询中做到这一点?我不想加载500个冲头,然后必须循环通过它们来获取任何附件(如果有的话)。这将是一个5分钟的工作在良好的旧SQL。有时候,我对EF6的这些东西很感兴趣。如果你需要加载部分相关的实体,你需要使用匿名类型或DTO来投影你的查询。作为例外说明,您只能在
Include
扩展方法中引用导航属性
foreach(var r in result2 ) 
{ 
    foreach(var a in r.Attachments) 
     {
       //your code; 
     }
}