EF子查询无导航属性

本文关键字:导航 属性 查询 EF | 更新日期: 2023-09-27 18:29:08

我正在尝试基于子查询计算布尔字段

  var dtfs = cntx.Set<Models.DocTypeField>()
                 .Include(dtf => dtf.Field)
                 .Where(dtf => dtf.DocTypeId == docTypeId)
                 .Select(dtf => new
            {
                DocTypeField = dtf,
                HasData = (cntx.Set<Models.DocumentData>()
                               .Any(dd => dd.DocTypeId == dtf.DocTypeId 
                                 && dd.DataValues.Any(ddv => ddv.FieldId == dtf.FieldId)))
            });

DocTypeFieldDocumentData之间没有导航属性(或可遍历路径)。当我运行上面的查询时,我得到以下异常:

测试方法

Core.Sebring.DataAccess.Ef.Test.EF_DocTypeDALTest.EF_DocTypeDALTest_GetDocTypeIndexes
 threw exception: 
System.NotSupportedException: 
  LINQ to Entities does not recognize the method 
  'System.Data.Entity.DbSet`1[Core.Sebring.Models.DocumentData] 
     Set[DocumentData]()' method, and this method cannot be translated 
     into a store expression.

是否有一种linq到实体的方式来完成上述查询?如果可能的话,我宁愿不在DocTypeFieldDocumentData之间添加导航属性(或可遍历路径)。

*更新1*作为一项工作,我做了

class FieldDocTypeField
    {
        public int DocTypeFieldId { get; set; }
        public int DocTypeId { get; set; }
        public int FieldDataType { get; set; }
        public int FieldId { get; set; }
        public byte[] LastChanged { get; set; }
        public bool Required { get; set; }
        public string FieldName { get; set; }
        public bool HasData { get; set; }
    }
var dtfs = cntx.DbContext.Database.SqlQuery<FieldDocTypeField>(@"select dtf.*,f.*,
            HasData = (CASE  WHEN EXISTS(Select DocumentDataValue.FieldId 
            from DocumentData 
            inner join DocumentDataValue on DocumentData.DocumentDataId=DocumentDataValue.DocumentDataId
            where DocumentData.DocTypeId = @DocTypeId AND dtf.FieldId = 1) THEN cast(1 as bit) ELSE cast(0 as bit) END)
            from DocTypeField dtf
            inner join Field f on dtf.FieldId = f.FieldId WHERE dtf.DocTypeId=@DocTypeId", new System.Data.SqlClient.SqlParameter("@DocTypeId", docTypeId));
            foreach (var dtf in dtfs)
            {
                docTypeFields.Add(new Models.DocTypeField
                {
                    DocTypeFieldId = dtf.DocTypeFieldId,
                    DocTypeId = dtf.DocTypeId,
                    FieldDataType = dtf.FieldDataType,
                    FieldId = dtf.FieldId,
                    LastChanged = dtf.LastChanged,
                    Required = dtf.Required,
                    FieldName = dtf.FieldName,
                    HasData = dtf.HasData
                });
            }

它不太好,但它起作用并完成了同样的事情。如果不在DocTypeFieldDocumentData实体之间添加nav属性,我找不到使用linq到实体执行上述操作的方法。

EF子查询无导航属性

您可以先提取内存中的数据,然后执行第二个select

var dtfs = cntx.Set<Models.DocTypeField>()
    .Include(dtf => dtf.Field)
    .Where(dtf => dtf.DocTypeId == docTypeId)
    .ToList() // pull the data to memory and then the following select can execute successfully.
    .Select(dtf => new
    {
        DocTypeField = dtf,
        HasData = (cntx.Set<Models.DocumentData>()
            .Any(dd => dd.DocTypeId == dtf.DocTypeId
                       && dd.DataValues.Any(ddv => ddv.FieldId == dtf.FieldId)))
    });