c# - LINQ多对多关系,如何写出正确的WHERE子句?

标签 c# linq entity-framework-4 dbcontext

我对表使用多对多关系。

有一个查询:

var query = from post in context.Posts
        from tag in post.Tags where tag.TagId == 10
        select post;

好的,它工作正常。我收到的帖子具有由 id 指定的标签。

我有一组标签 ID。我想获得包含我收藏中所有标签的帖子。

我尝试以下方式:

var tagIds = new int[]{1, 3, 7, 23, 56};

var query = from post in context.Posts
        from tag in post.Tags where tagIds.Contains( tag.TagId )
        select post;

这是行不通的。查询返回具有任何一个指定标签的所有帖子。

我想得到这样的子句,但动态地针对集合中的任意数量的标签:

post.Tags.Whare(x => x.TagId = 1 && x.TagId = 3 && x.TagId = 7 && ... )

最佳答案

您不应该在外部 查询中投影每个帖子的标签;相反,您需要使用一个内部查询来执行对外部过滤器的检查。 (在 SQL 中,我们过去称它为 correlated subquery。)

var query = 
    from post in context.Posts
    where post.Tags.All(tag => tagIds.Contains(tag.TagId))
    select post;

替代语法:

var query = 
    context.Posts.Where(post =>
        post.Tags.All(tag => 
            tagIds.Contains(tag.TagId)));

编辑:根据 Slauma’s clarification 更正.下面的版本返回的帖子至少包含 tagIds 集合中的所有标签。

var query = 
    from post in context.Posts
    where tagIds.All(requiredId => post.Tags.Any(tag => tag.TagId == requiredId))
    select post;

替代语法:

var query = 
    context.Posts.Where(post => 
        tagIds.All(requiredId => 
            post.Tags.Any(tag =>
                tag.TagId == requiredId)));

编辑2:根据 Slauma 更正了上面的内容。还包括另一种充分利用以下查询语法的替代方法:

// Project posts from context for which
// no Ids from tagIds are not matched
// by any tags from post
var query =
    from post in context.Posts
    where
    ( 
        // Project Ids from tagIds that are
        // not matched by any tags from post
        from requiredId in tagIds
        where
        (
            // Project tags from post that match requiredId
            from tag in post.Tags
            where tag.TagId == requiredId
            select tag
        ).Any() == false
        select requiredId 
    ).Any() == false
    select post;

我使用 .Any() == false 来模拟 Transact-SQL 中的 NOT EXISTS 运算符。

关于c# - LINQ多对多关系,如何写出正确的WHERE子句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10505595/

相关文章:

c# - 删除和更新查询在 ADO.NET 中不起作用

c# - AutoMapper - 自定义对象列表的 int 数组

c# - 如何在 XML 中保存 WPF 用户设置?

c# - 使用 Entity Framework 将更改保存回数据库

c# - 使用 Entity Framework 4 将大量行插入到 SQL CE 4.0(性能问题)

c# - 像 EntityFramework 6 中那样在 System.Data.Linq.DataContext 中记录执行时间

sql - Entity Framework (LINQ) 可以根据 JSON where 子句选择行吗?

时间:2019-03-08 标签:c#linqwhereconditionalif

c# - 日期时间转移到下一个预定义日期

asp.net-mvc-3 - 我的模型应该如何将动态添加的文本框的数据存储在数据库中?