c# - 查找子集合包含列表所有元素的行

标签 c# linq nhibernate

给定一个简单的博客引擎,其中包含帖子和与帖子关联的标签。 数据库中有 2 个表:PostTag , 还有 PostTag多对多关系表。

我有标签列表,我想找到所有包含所有这些标签的帖子(所以 .IsIn() 在这里不起作用)

问题:如何使用 nhibernate 实现它? (最好使用 .QueryOver<>() 方法)

这里的问题是我什至不知道从哪里开始以及如何用纯 SQL 实现它。我有两个想法:

  1. 获取所有帖子,然后使用 LINQ 过滤它们(即使用 .IsSupersetOf() 函数)
  2. 在 SQL 中使用 WHERE EXISTS对于列表中的每一项

但我相信还有更优雅的方式

表格结构

    CREATE TABLE Post (
        Id INT PRIMARY KEY, 
        Title NVARCHAR(255) NOT NULL
    );

    CREATE TABLE Tag (
        Id INT PRIMARY KEY, 
        Tag NVARCHAR(50) NOT NULL
    );

    CREATE TABLE PostTag (
        PostId INT NOT NULL REFERENCES Post(Id),
        TagId INT NOT NULL REFERENCES Tag(Id)
    );

    INSERT INTO Post(Id, Title) VALUES (1, 'Post A');
    INSERT INTO Post(Id, Title) VALUES (2, 'Post B');
    INSERT INTO Post(Id, Title) VALUES (3, 'Post C');

    INSERT INTO Tag(Id, Tag) VALUES (1, 'tagA');
    INSERT INTO Tag(Id, Tag) VALUES (2, 'tagB');

    INSERT INTO PostTag (PostId, TagId) VALUES (1, 1);
    INSERT INTO PostTag (PostId, TagId) VALUES (2, 2);
    INSERT INTO PostTag (PostId, TagId) VALUES (3, 1);
    INSERT INTO PostTag (PostId, TagId) VALUES (3, 2);

我想通过给定的标签 ID 列表获取 ID 为 3 的帖子:(1, 2)

最佳答案

在解决方案上使用 Query 应该如下所示,

Tag tagAlias = new Tag();
Post postAlias = new Post();

Tag tagAliasInner = new Tag();
Post postAliasInner = new Post();

var subQuery = QueryOver.Of(() => postAliasInner)
    .JoinAlias(() => postAliasInner.Tags, () => tagAliasInner)
    .Where(Restrictions.EqProperty(Projections.Property(() => postAliasInner.Id),
        Projections.Property(() => postAlias.Id)))
    .Where(Restrictions.In(Projections.Property(() => tagAliasInner.Id), ids.ToArray()))
    .Select(Projections.Count(Projections.Property(() => tagAliasInner.Id)));

var query = session.QueryOver(() => postAlias)
    .JoinAlias(() => postAlias.Tags, () => tagAlias)
    .Where(Restrictions.In(Projections.Property(() => tagAlias.Id), ids.ToArray()))
    .WithSubquery.WhereValue(ids.Count).Eq<Post>(subQuery);

var results = query.List();

这会产生 SQL,

SELECT this_.Id as Id3_1_,
 this_.Title as Title3_1_,
 tags3_.Post_id as Post1_,
 tagalias1_.Id as Tag2_,
 tagalias1_.Id as Id5_0_,
 tagalias1_.Text as Text5_0_ 
FROM "Post" this_
 inner join PostTag tags3_ on this_.Id=tags3_.Post_id 
 inner join "Tag" tagalias1_ on tags3_.Tag_id=tagalias1_.Id 
WHERE tagalias1_.Id in (?, ?) 
 and ? = (SELECT count(tagaliasin1_.Id) as y0_ 
            FROM "Post" this_0_
            inner join PostTag tags3_ on this_0_.Id=tags3_.Post_id 
            inner join "Tag" tagaliasin1_ on tags3_.Tag_id=tagaliasin1_.Id 
            WHERE this_0_.Id = this_.Id and tagaliasin1_.Id in (?, ?))

关于c# - 查找子集合包含列表所有元素的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34804002/

相关文章:

c# - 执行阅读器 : CommandText property has not been initialized when using gridView

c# - ServiceStack:测试 OrmLite,与 NuGet 一起安装但出现错误 "FileNotFoundException"

c# - 是否有编译为机器代码的 C C++ C# 编译器

linq - 如何使用 LINQ 等待 ParallelQuery?

c# - Linq where in 子句

winforms - 使用 NHibernate 在多个数据库之间复制实体

nhibernate - 扩展 NHibernate 以支持聚合函数

c# - 具有多个具有相同值的项目时的 AutoCompleteBox 问题

json - Newtonsoft.Json.Linq.JArray.GetEnumerator() 方法未找到

c# - 我可以传入 T.Property 吗?另外,改进这种方法的想法?