简体   繁体   English

具有包含问题的实体框架Linq

[英]Entity Framework Linq with Includes Issue

I have the following schema: 我有以下架构:

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
}

With this schema, there are a series of document groups and document types (think "buckets") a user can submit documents to. 使用此架构,用户可以提交一系列文档组和文档类型(例如“存储桶”)。 With each document type, there can be a series of keywords (via bridge XRef table). 对于每种文档类型,可以有一系列关键字(通过桥XRef表)。 When a document is submitted, the master ID is stored in the DocMaster table and the keyword values are stored in the Master_Index table (along with the master_id and doctype_id ). 提交文档后,主ID将存储在DocMaster表中,关键字值也将存储在Master_Index表中(以及master_iddoctype_id )。

My issue is, I'm working on a "search" query - when a user navigates to a page and presses search, they are presented with a dynamically generated list of inputs containing "From Date" and "Thru Date" as well as all the keywords for that specific document type. 我的问题是,我正在处理“搜索”查询-当用户导航到页面并按搜索时,会向他们显示动态生成的输入列表,其中包含“从日期”和“通过日期”以及所有该特定文档类型的关键字。 When the user hits the search button, the system is supposed to query based on all available values the user filled in (blank values are allowed). 当用户点击搜索按钮时,系统应该根据用户填写的所有可用值进行查询(允许使用空白值)。 However, I'm having trouble building my Linq-to-Entities query. 但是,我在构建Linq-to-Entities查询时遇到了麻烦。

What I have so far: 到目前为止,我有:

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;
}

The problem I am having is it's returning all instances of the keywords regardless of the document type - I need to filter the .Include of the Master_Index table, but it throws an ArgumentException error 我遇到的问题是,它无论返回的文档类型的关键字的所有实例-我需要过滤.Include中的Master_Index表,但它抛出一个ArgumentException错误

The Include path expression must refer to a navigation property defined on the type. 包含路径表达式必须引用在类型上定义的导航属性。 Use dotted paths for reference navigation properties and the Select operation for collection navigation properties 使用虚线路径作为参考导航属性,使用“选择”操作作为集合导航属性

How can I modify my Linq query to search for all my provided criteria, and fill the navigation properties? 如何修改Linq查询以搜索我提供的所有条件,并填充导航属性? I'm hoping to avoid multiple queries to the database if I can. 我希望能避免对数据库的多个查询。

Update 更新资料

Thanks to feedback from Lajos' comment, I went back to the drawing board (litterally a went to a white board) and re-wrote the function. 多亏了Lajos的评论反馈,我回到了绘图板(后来变成了白板),并重新编写了该功能。 I have broken the query down into two queries. 我已将查询分为两个查询。 The first one to return the list of docmaster_id 's that match the search criteria and the second one to fill in the associated keywords reguardless of values existing or not (I need at least the labels of the keywords to print on the screen) 第一个返回匹配搜索条件的docmaster_id的列表,第二个返回不考虑是否存在值的情况下填充关联的keywords (我至少需要在屏幕上打印关键字的标签)

Thanks to feedback from Lajos' comment, I went back to the drawing board (litterally a went to a white board) and re-wrote the function. 多亏了Lajos的评论反馈,我回到了绘图板(后来变成了白板),并重新编写了该功能。 I have broken the query down into two queries. 我已将查询分为两个查询。 The first one to return the list of docmaster_id's that match the search criteria and the second one to fill in the associated keywords reguardless of values existing or not (I need at least the labels of the keywords to print on the screen) 第一个返回与搜索条件匹配的docmaster_id列表,第二个返回相关关键字的填充,无论是否存在现有值(我至少需要在屏幕上打印这些关键字的标签)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM