Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq到加入集合和筛选的对象_C#_Linq_Entity Framework_Linq To Objects - Fatal编程技术网

C# Linq到加入集合和筛选的对象

C# Linq到加入集合和筛选的对象,c#,linq,entity-framework,linq-to-objects,C#,Linq,Entity Framework,Linq To Objects,我在使用Linq to对象过滤/连接内存中的对象列表时遇到问题,通常是一个简单的SQL查询 场景: 拥有json服务(.asmx)允许客户端通过实体框架包装的存储过程(函数导入)进行DB调用。在本例中,[Web方法]“GetArticles(int[]TagIds)” 我现在希望缓存这些数据以保存DB调用,并对缓存的集合应用过滤器 数据: 与2个实体的多对多关系:文章、标签 文章可以有许多标记,并且标记可以与许多文章关联(因此额外的链接表'ArticlesTags') web服务筛选器参数将

我在使用Linq to对象过滤/连接内存中的对象列表时遇到问题,通常是一个简单的SQL查询

场景:
拥有json服务(.asmx)允许客户端通过实体框架包装的存储过程(函数导入)进行DB调用。在本例中,[Web方法]“GetArticles(int[]TagIds)”
我现在希望缓存这些数据以保存DB调用,并对缓存的集合应用过滤器

数据:

  • 与2个实体的多对多关系:文章、标签
  • 文章可以有许多标记,并且标记可以与许多文章关联(因此额外的链接表'ArticlesTags')
web服务筛选器参数将包含返回的文章可以具有的标记ID数组

所以我的基线SQL查询看起来是这样的

SELECT DISTINCT a.*
FROM Article a INNER JOIN ArticlesTags at ON a.ArticleId = at.ArticleId
WHERE at.TagId in (0, 1.. 'list of tag ids')
我遇到了很多障碍-
EF包装的存储过程不允许SQL 2008(表值参数),因此我无法以首选格式传入TagId列表筛选器。 我发现了一个示例,其中一个存储过程调用可以返回两个结果集,这可能会解决这个问题。 因此,一旦我有了要缓存的两个集合(Articles和ArticleStag),如何使用linq to对象连接并随后基于可能的TagId的filter参数进行过滤?

以下是一种在linq中“重写”SQL查询的方法:

class Article {
    public int ArticleId;
    public string ArticleName;
    // Other fields...
}

class ArticleComparer : IEqualityComparer<Article> {
    public bool Equals(Article x, Article y) {
        return x.ArticleId == y.ArticleId && x.ArticleName == y.ArticleName;
    }
    public int GetHashCode(Article obj) {
        return obj.ArticleId.GetHashCode();
    }
}

class ArticlesTag {
    public int TagId;
    public int ArticleId;
    // Other fields...
}

class Program {

    static void Main(string[] args) {

        // Test data:

        var articles = new[] {
            new Article { ArticleId = 1, ArticleName = "Article A" },
            new Article { ArticleId = 2, ArticleName = "Article B" },
            new Article { ArticleId = 3, ArticleName = "Article C" }
        };

        var article_tags = new[] {
            new ArticlesTag { TagId = 1, ArticleId = 1 },
            new ArticlesTag { TagId = 2, ArticleId = 1 },
            new ArticlesTag { TagId = 3, ArticleId = 1 },
            new ArticlesTag { TagId = 4, ArticleId = 2 },
            new ArticlesTag { TagId = 5, ArticleId = 2 },
            new ArticlesTag { TagId = 6, ArticleId = 3 },
            new ArticlesTag { TagId = 7, ArticleId = 3 }
        };

        var tag_ids = new HashSet<int>(new[] { 2, 3, 6 });

        // JOIN "query":

        var q = (
            from article in articles
            join article_tag in article_tags
                on article.ArticleId equals article_tag.ArticleId
            where tag_ids.Contains(article_tag.TagId)
            select article
        ).Distinct(new ArticleComparer());

        foreach (var article in q)
            Console.WriteLine(
                string.Format(
                    "ArticleId = {0}\tArticleName = {1}",
                    article.ArticleId,
                    article.ArticleName
                )
            );

    }

}

因此,您有一个Article表、一个Tags表和一个ArticleTags表,该表将Articles ID与一个Tags ID关联起来。然后遍历ArticleTags并获取与该articles ID匹配的所有TagID,然后遍历标记以获取与该标记ID相关联的名称。将其转换为一个整洁的字典,其中包含一个键标记名,该值是标记名的IEnumerable。(您可以为Dictionary而不是Dictionary提取整个文章和整个标记,只需省略成员选择器

var articleDictionary = articles.ToDictionary(
       a => a.Name, // article name is key
       a => ArticleTags
             .where(t => t.ArticleID == a.Id)
             .select(t => Tags.Single(tag => tag.id == t.id).TagName // value is an IEnumerable<string> of tag names
)

foreach (var article in articleDictionary)
{
    Console.WriteLine(article.Key);
    foreach (var tag in article.Value)
    { 
        Console.WriteLine("\t" + tag)
    }
}
var articleDictionary = articles.ToDictionary(
       a => a.Name, // article name is key
       a => ArticleTags
             .where(t => t.ArticleID == a.Id)
             .select(t => Tags.Single(tag => tag.id == t.id).TagName // value is an IEnumerable<string> of tag names
)

foreach (var article in articleDictionary)
{
    Console.WriteLine(article.Key);
    foreach (var tag in article.Value)
    { 
        Console.WriteLine("\t" + tag)
    }
}
var articleDictionary = articles.ToDictionary(
       a => a,
       a => ArticleTags
             .where(t => t.ArticleID == a.Id)
             .select(t => Tags.Single(tag => tag.id == t.id)
)