实体框架Linq包含问题

本文关键字:问题 包含 Linq 框架 实体 | 更新日期: 2023-09-27 18:04:58

我有以下模式:

DMS_DocMaster {
    docmaster_id int,
    createddate datetime,
}
DMS_Master_Index {
    doctype_id int
    keyword_id int
    docmaster_id int
}
DMS_DocTypes {
    doctype_id int
    group_id int
    description varchar(50)
}
DMS_Keywords {
    keyword_id int
    label varchar(50)
    datatype varchar(50)
}
DMS_Doc_Keyword_XRef {
    doctype_id int
    keyword_id int
    seqorder int
}

在这个模式下,有一系列的文档组和文档类型(想象一下"桶"),用户可以将文档提交到其中。对于每种文档类型,都可以有一系列关键字(通过桥接XRef表)。当提交文档时,主ID存储在DocMaster表中,关键字值存储在Master_Index表中(以及master_iddoctype_id)。

我的问题是,我正在研究一个"搜索"查询-当用户导航到一个页面并按下搜索时,他们会看到一个动态生成的输入列表,其中包含"From Date"answers"Thru Date"以及该特定文档类型的所有关键字。当用户点击搜索按钮时,系统应该根据用户填写的所有可用值(允许空白值)进行查询。但是,我在构建链接到实体查询时遇到了麻烦。

目前为止我有什么:

public IList<DMS_DocMaster> SearchDocuments(int groupId = -1, int typeId = -1, DateTime? fromDate = null, DateTime? thruDate = null, Dictionary<int, string> searchCriteria = null)
{
    List<DMS_DocMaster> results;
    using (var ctx = new DMSEntities())
    {
        //make sure Lazy Loading is off because we are including reference tables in the results
        //and the context will be closed at time of accessing reference tables --> exception thrown
        ctx.Configuration.LazyLoadingEnabled = false;
        //initial query regardless of type or not
        //it's an anonymous type to make sure all fields are included
        var res = from docMaster in ctx.DMS_DocMaster.Include(x => x.DMS_Notes)
                  join masterIndex in ctx.DMS_Master_Index on docMaster.docmaster_id equals masterIndex.docmaster_id
                  join docTypes in ctx.DMS_DocTypes on masterIndex.doctype_id equals docTypes.doctype_id
                  //join xref in ctx.DMS_Doc_Keyword_XRef on masterIndex.doctype_id equals xref.doctype_id
                  //join keys in ctx.DMS_Keywords on xref.keyword_id equals keys.keyword_id
                  where docTypes.group_id == groupId
                  //select new { docMaster, masterIndex, docTypes, xref, keys };
                  select new { docMaster, masterIndex, docTypes };
        //if type is provided, search against the type
        if (typeId > 0)
        {
            res = res.Where(i => i.docTypes.doctype_id == typeId);
        }
        //if there is a from date
        if (fromDate.HasValue)
        {
            res = res.Where(i => i.docMaster.createdate >= fromDate.Value);
        }
        //if there is a thru date
        if (thruDate.HasValue)
        {
            res = res.Where(i => i.docMaster.createdate <= thruDate.Value);
        }
        //if we have search criteria
        if (searchCriteria != null)
        {
            //loop over it, appending where clauses
            foreach (var criterion in searchCriteria)
            {
                 res = res.Where(i => i.masterIndex.keyword_id == criterion.Key && i.masterIndex.keyword_value.Equals(criterion.Value));
            }
        }
        //select just the Doc Master records from the anonymous type
        //include the Master Index reference table, and the links to the Keywords table
        //to get the keyword label
        var res1 = res.Select(i => i.docMaster);
        res1 = res1.Include(x => x.DMS_Notes);
        res1 = res1.Include(x => x.DMS_Master_Index);
        //res1 = res1.Include(x => x.DMS_Master_Index
        //  .Select(y => y.DMS_Doc_Keyword_XRef.DMS_Keywords));
        res1 = res1.Include(x => x.DMS_Master_Index.Where(y => y.doctype_id == typeId));  //this throws an error
        res1 = res1.OrderByDescending(i => i.createdate);
        results = res1.ToList();
    }
    return results;
}

我遇到的问题是,无论文档类型如何,它都返回关键字的所有实例-我需要过滤Master_Index表的.Include,但它抛出ArgumentException错误

Include路径表达式必须引用在该类型上定义的导航属性。引用导航属性使用点点路径,集合导航属性使用Select操作

如何修改我的Linq查询来搜索我提供的所有条件,并填充导航属性?如果可以,我希望避免对数据库进行多次查询。

感谢Lajos的评论反馈,我回到了绘图板(字面上说是白板)并重新编写了函数。我将查询分解为两个查询。第一个返回匹配搜索条件的docmaster_id列表,第二个填写相关的keywords,而不管值是否存在(我至少需要在屏幕上打印关键字的标签)

实体框架Linq包含问题

感谢Lajos的评论反馈,我回到绘图板上(实际上是到白板上)重新编写了这个函数。我将查询分解为两个查询。第一个返回与搜索条件匹配的docmaster_id的列表,第二个用于填写关联的关键字,而不管值是否存在(我至少需要关键字的标签在屏幕上打印)