首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用多查找的复杂查询

使用多查找的复杂查询
EN

Stack Overflow用户
提问于 2011-02-21 20:52:32
回答 2查看 2.5K关注 0票数 1

我正在尝试获取一个列表中的项目,其中任何一个多重查找值都包含在另一个查询的结果中。

情况是这样的:我正在构建一个set部件,用户可以使用一组sharepoint (foundation 2010)列表为五个属性下拉列表生成报告(“融合”)。这些属性通过列表中的查找进行连接。每次更改下拉列表选择时,都会发生回发,并重新填充以下下拉列表。

问题是属性之间的连接并不是与下拉列表直接匹配的。这是因为选择下拉输入是为了直观地输入报告,而数据模型是为了方便和直观地输入系统数据而设计的,而不是为了高效和容易的编程而设计的。

数据模型的相关部分:

-Locaties (位置)是一个列表

-Contracten (合同)是一个列表,每个合同都有一个或多个位置(多查找)

-Urgentie (紧急)是一个列表,每个紧急事件都有一个契约(查找)

-Meldingtypes (reporttype)是一个列表

类别( -Categorieën )是一个列表,每个类别有一个meldingtype (查找),每个类别有一个或多个契约(多个查找)

报告输入如下:

用户首先选择位置

用户选择Meldingtype秒

用户选择第三个类别

用户选择第四个合同

最后,用户选择Urgentie

当然,每次下拉列表都应该只填充有效的选项。因此,当选择一个位置时,下拉列表中显示的唯一meldingtypes应该是那些具有所选location...yeah的合同的类别;)

我在创建查询来填充dropdowns时遇到了问题。我已经尝试了几种方法,包括多个查询,使用Contains选择器的构造,但都没有成功。在上一次迭代中,我创建了一个查询,该查询使用一个项在被多查找引用时所具有的属性。下面是meldingtype下拉列表的示例:

代码语言:javascript
复制
    private void fillMeldingtypeDropdown(Intermediair.IntermediairDataContext idctx)
    {
        var meldingtypeData = (from l in idctx.Locaties
                               from co in l.ContractenItem
                               from ca in co.CategorieënItem
                               where l.Id == selectedLocatieId
                               select ca.Meldingtype
                              ).Distinct<Intermediair.Item>();
        foreach (Intermediair.Item meldingtype in meldingtypeData)
        {
            ctrl_Meldingtype.Items.Add(new ListItem(meldingtype.Titel, meldingtype.Id.ToString()));
        }
    }

selectedLocatieId是一个从Locatie下拉控件获取值的属性。

上面的代码抛出了一个System.InvalidOperationException。错误描述是荷兰语,翻译过来应该是这样的:“查询使用了不受支持的元素,比如引用多个列表或使用EntityRef/EntitySet投影完整的实体。”

如果我使用EntitySet.Contains,我会得到同样的错误:

代码语言:javascript
复制
    private void fillCategorieDropdown(Intermediair.IntermediairDataContext idctx)
    {
        var contractenData = from c in idctx.Contracten
                             where c.LocatieS.Contains( 
                                 (  from l in idctx.Locaties 
                                    where l.Id == selectedLocatieId 
                                    select l
                                 ).First<Intermediair.LocatiesItem>() 
                             )
                             select c;
        var categorieenData = ( from ca in idctx.Categorieën
                                from co in contractenData
                                where ca.Contract.Contains(co) && ca.Meldingtype.Id == selectedMeldingtypeId
                                select ca
                              ).Distinct<Intermediair.CategorieënItem>();
        foreach (var categorie in categorieenData)
        {
            ctrl_Categorie.Items.Add(new ListItem(categorie.Titel, categorie.Id.ToString()));
        }
    }

我尝试了几种排列,但似乎找不到合适的。我找不到任何使用多查找字段的linq-to-sharepoint查询的好例子,而且我对linq还不够熟练,所以我可能犯了一些重大错误。在我弄清楚这一点的同时,我真的很感激任何有用的想法。

编辑:另一次尝试失败我尝试对所有步骤进行单独查询以检查中间结果。我还尝试了一个Any-Contains组合,将categorie的多个查找合同与我从该位置获得的多个合同进行匹配。

代码语言:javascript
复制
        var locatieItem = (from l in idctx.Locaties
                           where l.Id == selectedLocatieId
                           select l
                          ).First();
        var contractenData = from c in locatieItem.ContractenItem
                             select c;
        var categorieenData = from c in idctx.Categorieën
                              where c.Contract.Any(co => contractenData.Contains(co))
                              select c;
        var meldingtypeData = (from c in categorieenData
                               select c.Meldingtype
                              ).Distinct();
        foreach (var meldingtype in meldingtypeData)
        {
            ctrl_Meldingtype.Items.Add(new ListItem(meldingtype.Titel, meldingtype.Id.ToString()));
        }

locatieItem和contractenData按预期填充,但categorieenData再次生成相同的错误。/Edit

另外,因为代码中的荷兰语名字在英文中非常易读,所以我没有翻译这些名字。很抱歉给你造成了混乱。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-01 19:19:47

我已经解决了这个问题。它确实带来了一些开销:从数据库中检索了太多的记录。但只有重复,所以希望缓存能解决大部分开销。

我现在使用的查询非常简单。

代码语言:javascript
复制
        var categorieenContractenData = from c in contractenData
                                        select c.CategorieënItem;

这不是给我一组CategorieItems,而是一组CategorieItems,其中一些可以是重复的。然后,我使用一个双foreach循环遍历每个条目,并将这些条目放入三个数据结构中,以便于检索。这意味着要填充这三个下拉列表中的每一个,我只需执行一次linq-query。

我预计本周末数据库中会有一些真实的数据,因此我将测试它是否足够快。如果没有,我将不得不做一个额外的列表(由事件接收者填写)。

完整代码:

代码语言:javascript
复制
    private void ensureLoadData(Intermediair.IntermediairDataContext idctx)
    {
        if (dataLoaded) return;

        meldingtypes = new SortedList<string, int?>();
        categorieen = new SortedList<int?,SortedList<string,int?>>();
        contracten = new SortedList<int?, SortedList<int?, SortedList<string, int?>>>();
        IQueryable<Intermediair.ContractenItem> contractenData = from c in
                                                                     (from l in idctx.Locaties
                                                                      where l.Id == selectedLocatieId
                                                                      select l
                                                                     ).SingleOrDefault().ContractenItem
                                                                 select c;
        var categorieenContractenData = from c in contractenData
                                        select c.CategorieënItem;
        foreach (EntitySet<Intermediair.CategorieënItem> categorieenPerContract in categorieenContractenData)
        {
            foreach (Intermediair.CategorieënItem categorie in categorieenPerContract)
            {
                if (!meldingtypes.ContainsKey(categorie.Meldingtype.Titel))
                {
                    meldingtypes.Add(categorie.Meldingtype.Titel, categorie.Meldingtype.Id);
                    categorieen.Add(categorie.Meldingtype.Id, new SortedList<string,int?>());
                    contracten.Add(categorie.Meldingtype.Id, new SortedList<int?, SortedList<string, int?>>());
                }
                if (!categorieen[categorie.Meldingtype.Id].ContainsKey(categorie.Titel))
                {
                    categorieen[categorie.Meldingtype.Id].Add(categorie.Titel, categorie.Id);
                    contracten[categorie.Meldingtype.Id].Add(categorie.Id, new SortedList<string,int?>());
                    foreach (Intermediair.ContractenItem contract in categorie.Contract)
                    {
                        contracten[categorie.Meldingtype.Id][categorie.Id].Add(contract.Titel, contract.Id);
                    }
                }
            }
        }
        dataLoaded = true;
    }
票数 0
EN

Stack Overflow用户

发布于 2011-02-21 22:58:52

在SharePoint 2010中,linq有一些限制。也许这篇文章可以帮你找到正确的方向:http://www.chaholl.com/archive/2010/03/12/joins-in-linq-to-sharepoint-2010.aspx

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5066194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档