0

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

目前我只有:

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

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


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

再次感谢任何帮助!

4

3 回答 3

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();
于 2012-07-18T05:18:59.957 回答
1

你也可以试试这个,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;
    }
于 2012-07-18T08:25:27.260 回答
0

以为我会弹出并分享我的解决方案,这与我最初想到的完全不同。

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

当我第一次填写表单时,我只显示与文档有关系的所有标签。之后使用我的搜索过滤器,当在 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;
        }

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

于 2012-09-14T17:54:25.437 回答