gpt4 book ai didi

Nhibernate 标签云查询

转载 作者:行者123 更新时间:2023-12-02 04:18:25 26 4
gpt4 key购买 nike

到目前为止,这对我来说已经是 2 周的战斗,没有运气。 :(

先说一下我的目的。能够搜索标记为“foo”的实体 “酒吧”。不会觉得太难了吧?

我知道这可以使用 HQL 轻松完成,但因为这是一个动态构建的搜索查询,不是一个选项。首先是一些代码:

public class Foo 
{
public virtual int Id { get;set; }
public virtual IList<Tag> Tags { get;set; }
}

public class Tag
{
public virtual int Id { get;set; }
public virtual string Text { get;set; }
}

映射为多对多,因为 Tag 类用于许多不同的类型。因此没有双向引用。

所以我使用抽象过滤器类建立我的分离标准。让我们假设为简单起见,我只是在搜索带有标签“Apples”(TagId1)&&“Oranges”(TagId3)的Foos,这看起来像。

SQL:
SELECT ft.FooId
FROM Foo_Tags ft
WHERE ft.TagId IN (1, 3)
GROUP BY ft.FooId
HAVING COUNT(DISTINCT ft.TagId) = 2; /*Number of items we are looking for*/

标准
var idsIn = new List<int>() {1, 3};
var dc = DetachedCriteria.For(typeof(Foo), "f").
.CreateCriteria("Tags", "t")
.Add(Restrictions.InG("t.Id", idsIn))
.SetProjection( Projections.ProjectionList()
.Add(Projections.Property("f.Id"))
.Add(Projections.RowCount(), "RowCount")
.Add(Projections.GroupProperty("f.Id")))
.ProjectionCriteria.Add(Restrictions.Eq("RowCount", idsIn.Count));
}
var c = Session.CreateCriteria(typeof(Foo)).Add(Subqueries.PropertyIn("Id", dc))

基本上,这是创建一个 DC,该 DC 转换具有指定所有标签的 Foo Id 列表。

这在 NH 2.0.1 中编译但没有工作,因为它提示找不到类 Foo 的属性“RowCount”。

看完 this发布我希望这可能会在 2.1.0 中修复,所以我升级了。令我极度失望的是,我发现 ProjectionCriteria 已从 DetachedCriteria 中删除,我无法弄清楚如何在没有 DetachedCriteria 的情况下使动态查询构建工作。

所以我试图思考如何在不需要臭名昭著的Having 子句的情况下编写相同的查询。可以通过标签表上的多个连接来完成。万岁,我认为这很简单。所以我把它改写成这样。
var idsIn = new List<int>() {1, 3};
var dc = DetachedCriteria.For(typeof(Foo), "f").
.CreateCriteria("Tags", "t1").Add(Restrictions.Eq("t1.Id", idsIn[0]))
.CreateCriteria("Tags", "t2").Add(Restrictions.Eq("t2.Id", idsIn[1]))

徒劳地尝试产生下面的sql来完成这项工作(我意识到它不太正确)。
SELECT f.Id
FROM Foo f
JOIN Foo_Tags ft1
ON ft1.FooId = f.Id
AND ft1.TagId = 1
JOIN Foo_Tags ft2
ON ft2.FooId = f.Id
AND ft2.TagId = 3

不幸的是,我在这次尝试中遇到了第一个障碍,收到了“重复关联路径”异常。阅读 around这似乎是 ancient并且仍然非常真实的错误/限制。

我错过了什么?

我开始诅咒 NHibernates 的名字,让你认为什么是你认为如此简单和常见的查询,如此困难。请帮助任何曾经这样做过的人。你是如何绕过 NHibernates 限制的。

忘记声誉和赏金。如果有人在这方面对我有帮助,我会寄给你一个 6 包来解决你的麻烦。

最佳答案

我设法让它像这样工作:

var dc = DetachedCriteria.For<Foo>( "f")
.CreateCriteria("Tags", "t")
.Add(Restrictions.InG("t.Id", idsIn))
.SetProjection(Projections.SqlGroupProjection("{alias}.FooId", "{alias}.FooId having count(distinct t1_.TagId) = " + idsIn.Count,
new[] { "Id" },
new IType[] { NHibernateUtil.Int32 }));

这里唯一的问题是计数( t1_ .TagId) - 但我认为在这个 DetachedCriteria 中每次都应该生成相同的别名 - 所以你应该安全地进行硬编码。

关于Nhibernate 标签云查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1277971/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com