Linq 在实体框架中的查询中使用列表

Linq 在实体框架中的查询中使用列表,linq,sql-server-2008,c#-4.0,entity-framework-4,Linq,Sql Server 2008,C# 4.0,Entity Framework 4,我试图找到一种方法,将可选字符串列表传递给查询。我试图做的是根据标签之间的关系过滤标签列表。例如,如果选择了c#,我的程序将只建议在文档中显示带有c#标记的标记,然后在选择下一个标记时,例如SQL,将显示链接到这两个标记的文档的标记,并将其缩小,以便用户可以越来越接近他的目标 目前我所拥有的只是: List<Tag> _tags = (from t in Tags where t.allocateTagDoc.Count > 0

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

目前我所拥有的只是:

List<Tag> _tags =  (from t in Tags
                   where t.allocateTagDoc.Count > 0
                   select t).ToList();
List\u tags=(来自标记中的t
其中t.allocateTagDoc.Count>0
选择t.ToList();
这是在选择标记时使用可选参数重复调用的方法中


我想我一直在倒退。如果我对每个提供的标签进行两次(或更多)查询,找到它们一起出现的文档,然后拿出所有与它们一起出现的标签。。。还是说数据库的点击率太高了?我是否可以完全通过实体上下文变量来执行此操作,并仅查询模型

再次感谢您的帮助

你可以试试这个

首先收集要在字符串列表中搜索的标记

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

您也可以尝试这样做,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;
    }
字典文档=
新字典();
添加(1,新字符串[]{“C#”,“SQL”,“EF”});
添加(2,新字符串[]{“C#”,“Interop”});
添加(3,新字符串[]{“Javascript”,“ASP.NET”});
添加(4,新字符串[]{});
//返回属于ID为1、2的文档的标记
string[]filterTags=新字符串[]{“C#”};
var relatedTags=GetRelatedTags(文档、过滤器标签);
Debug.WriteLine(string.Join(“,”,relatedTags));
//返回属于ID为1的文档的标记
filterTags=新字符串[]{“C#”,“SQL”};
relatedTags=GetRelatedTags(文档、过滤器标签);
Debug.WriteLine(string.Join(“,”,relatedTags));
//返回属于所有文档的标记
//因为没有指定筛选标记
filterTags=新字符串[]{};
relatedTags=GetRelatedTags(文档、过滤器标签);
Debug.WriteLine(string.Join(“,”,relatedTags));
公共静态字符串[]GetRelatedTags(
字典文档,
字符串[]过滤器标签)
{
var documentsWithFilterTags=文档。其中(o=>
滤袋
.Intersect(o.Value).Count()==filterTags.Length);
string[]relatedTags=新字符串[0];
foreach(documentsWithFilterTags.Select(o=>o.Value)中的字符串[]标记)
relatedTags=relatedTags
.Concat(标签)
.Distinct()
.ToArray();
返回相关标签;
}

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

首先,我稍微修改了数据库,去掉了allocateDocumentTag表中的一个无用字段,这使我能够更有效地使用实体框架模型,因为我可以不使用该表,而完全通过标记和文档之间的关系来访问它

当我第一次填写表单时,我只显示与文档有关系的所有标记。使用我的搜索过滤器之后,当在checkedListBox中选择一个标记时,将返回与该标记关联的文档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;
        }
publicstaticlist-fillUsed(List-docid=null)
{
使用的列表=新列表();
if(docIds==null | | docIds.Count()<1)
{
used=(从frmFocus.\u context.Tags中的t开始)
其中t.Documents.Count>=1
选择t.ToList();
}
其他的
{    
used=(从frmFocus.\u context.Tags中的t开始)
其中t.Documents.Any(d=>docid.Contains(d.id))
选择t.ToList();
}
使用的退货;
}

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

非常感谢,我会尝试一下。如果我将ID从标记中传递,而不是字符串,会更容易吗?是的,您可以在那里传递ID,ID将在db查询中很好地执行。问题是我正在浏览一个已有的db,其中标记已经分配(或将由用户分配)。尽管字典绝对是个好主意。谢谢
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;
        }