【问题标题】:Using an list in a query in entity framework在实体框架的查询中使用列表
【发布时间】:2012-07-17 02:05:35
【问题描述】:

我正在尝试找到一种将可选字符串列表传递给查询的方法。我想做的是根据标签之间的关系过滤标签列表。例如,如果选择了 c#,我的程序将只建议出现在带有 ac# 标记的文档中的标记,然后在选择下一个(例如 SQL)时,将显示链接到文档的两个标记的标记,并对其进行削减让用户离他的目标越来越近。

目前我只有:

List<Tag> _tags =  (from t in Tags
                   where t.allocateTagDoc.Count > 0
                   select t).ToList();

这是一个在选择标签时会使用可选参数重复调用的方法。


我想我一直在搞反了。如果我为每个提供的标签进行两个(或更多)查询,找到它们一起出现的文档,然后带出所有与它们一起出现的标签......或者数据库上的点击次数过多?我可以完全通过实体上下文变量来完成它并只查询模型吗?

再次感谢您的帮助!

【问题讨论】:

    标签: linq sql-server-2008 c#-4.0 entity-framework-4


    【解决方案1】:

    你可以试试这个。

    首先收集标签以在字符串列表中搜索。

    List<string> tagStrings = new List<string>{"c#", "sql"};
    

    在您的查询中传递这个列表,检查它是否为空,如果为空,它将返回所有标签,否则将返回与 tagStrings 匹配的标签。

    var _tags = (from t in Tags 
                 where t.allocateTagDoc.Count > 0
                 && (tagStrings.Count ==0  || tagStrings.Contains(t.tagName))
                 select t).ToList();
    

    【讨论】:

    • 非常感谢,我试试看。
    • 如果我从标签中传递 ID 而不是字符串会更容易吗?
    • 是的,你可以在那里传递 ids,ids 将在 db 查询中很好地执行。
    【解决方案2】:

    你也可以试试这个,Dictionary 用它的标签表示一个文档的 ID:

            Dictionary<int, string[]> documents = 
                new Dictionary<int, string[]>();
    
            documents.Add(1, new string[] { "C#", "SQL", "EF" });
            documents.Add(2, new string[] { "C#", "Interop" });
            documents.Add(3, new string[] { "Javascript", "ASP.NET" });
            documents.Add(4, new string[] { });
    
            // returns tags belonging to documents with IDs 1, 2
            string[] filterTags = new string[] { "C#" };
            var relatedTags = GetRelatedTags(documents, filterTags);
            Debug.WriteLine(string.Join(",", relatedTags));
    
            // returns tags belonging to document with ID 1
            filterTags = new string[] { "C#", "SQL" };
            relatedTags = GetRelatedTags(documents, filterTags);
            Debug.WriteLine(string.Join(",", relatedTags));
    
            // returns tags belonging to all documents 
            // since no filtering tags are specified
            filterTags = new string[] { };
            relatedTags = GetRelatedTags(documents, filterTags);
            Debug.WriteLine(string.Join(",", relatedTags));
    
    
        public static string[] GetRelatedTags(
            Dictionary<int, string[]> documents, 
            string[] filterTags)
        {
            var documentsWithFilterTags = documents.Where(o => 
                filterTags
                    .Intersect(o.Value).Count() == filterTags.Length);
    
            string[] relatedTags = new string[0];
    
            foreach (string[] tags in documentsWithFilterTags.Select(o => o.Value))
                relatedTags = relatedTags
                    .Concat(tags)
                    .Distinct()
                    .ToArray();
    
            return relatedTags;
        }
    

    【讨论】:

    • 问题是我正在浏览一个现有的数据库,其中标签已经分配(或将由用户分配)。虽然字典绝对是个好主意。谢谢!
    【解决方案3】:

    我想我会回来分享我的解决方案,这与我最初的想法完全不同。

    首先,我稍微修改了数据库,去掉了 allocateDocumentTag 表中的一个无用字段,这使我能够更有效地使用实体框架模型,因为我允许我离开该表并完全通过 Tag 和之间的关系访问它文件。

    当我第一次填写表单时,我只显示与文档有关系的所有标签。之后使用我的搜索过滤器,当在 checkListBox 中选择一个标签时,与该标签关联的文档 ID 将被返回,然后被反馈以填充已使用的标签列表框。

    public static List<Tag> fillUsed(List<int> docIds = null)
            {
                List<Tag> used = new List<Tag>();
    
                if (docIds == null || docIds.Count() < 1)
                {
                    used = (from t in frmFocus._context.Tags
                            where t.Documents.Count >= 1
                            select t).ToList();  
                }
                else
                {    
                    used = (from t in frmFocus._context.Tags
                            where t.Documents.Any(d => docIds.Contains(d.id))
                            select t).ToList();  
                }
                return used;
            }
    

    标签从那里输入文档搜索,反之亦然。希望这可以帮助其他人,如果答案不清楚或者您需要更多代码,那么只需发表评论,我会尝试对其进行排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多