NHibernate:CreateCriteria 和 Exists 子句

发布于 2024-08-11 17:46:33 字数 153 浏览 13 评论 0原文

如何使用 CreateCriteria 编写以下 SQL:

SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)

How can I write the following SQL using CreateCriteria:

SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

时光清浅 2024-08-18 17:46:33

下面是如何做到这一点:

var fooBars = Session.CreateCriteria<FooBar>()
        .Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();

...假设 FooBar 对象中有一个集合属性(一对多)“Bazs”。

或者,您可以使用这样的独立标准:

DetachedCriteria dCriteria = DetachedCriteria.For<Baz>("baz")
        .SetProjection(Projections.Property("baz.FooBarId"))
        .Add(Restrictions.EqProperty("baz.FooBarId", "fooBar.Id"));

var fooBars = Session.CreateCriteria<FooBar>("fooBar")
        .Add(Subqueries.Exists(dCriteria)).List<FooBar>();

Here is how you can do it:

var fooBars = Session.CreateCriteria<FooBar>()
        .Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();

...assuming there is a collection property (one-to-many) "Bazs" in the FooBar object.

Alternatively you could use detached criteria like that:

DetachedCriteria dCriteria = DetachedCriteria.For<Baz>("baz")
        .SetProjection(Projections.Property("baz.FooBarId"))
        .Add(Restrictions.EqProperty("baz.FooBarId", "fooBar.Id"));

var fooBars = Session.CreateCriteria<FooBar>("fooBar")
        .Add(Subqueries.Exists(dCriteria)).List<FooBar>();
梦过后 2024-08-18 17:46:33

刚刚解决了一个相关问题并最终找到了一个解决方案,我想我应该在这里分享答案:

假设您想要原始问题查询,并在子查询上有一个附加条件:

SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id
              AND Quantity = 5)

假设您对 Baz 类有一个引用父级,称为 FooBarRef [在 Fluent Map 类中,您将使用 References() 方法],您将按如下方式创建查询:

DetachedCriteria dCriteria = DetachedCriteria.For<Baz>("baz")
        .SetProjection(Projections.Property("baz.FooBarId"))
        .Add(Expression.EqProperty("this.FooBarId", "FooBarRef.Id"))
        .Add(Expression.Eq("baz.Quantity", 5));

var fooBars = Session.CreateCriteria<FooBar>("fooBar")
        .Add(Subqueries.Exists(dCriteria)).List<FooBar>();

我不是 100% 相信别名“this”的硬编码,它是别名 NHibernate 自动分配给查询中的根实体(表),但这是我发现从子查询中引用父查询表的键的唯一方法。

Having just solved a related problem and eventually arrived at a solution I thought I'd share the answer here:

Assuming you want the original questions query, with an additional condition on the sub-query:

SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id
              AND Quantity = 5)

Assuming you have a reference on the Baz class to the parent, called, say FooBarRef [ in Fluent Map class you'd use the References() method ], you would create the query as follows:

DetachedCriteria dCriteria = DetachedCriteria.For<Baz>("baz")
        .SetProjection(Projections.Property("baz.FooBarId"))
        .Add(Expression.EqProperty("this.FooBarId", "FooBarRef.Id"))
        .Add(Expression.Eq("baz.Quantity", 5));

var fooBars = Session.CreateCriteria<FooBar>("fooBar")
        .Add(Subqueries.Exists(dCriteria)).List<FooBar>();

I'm not 100% convinced about hard coding of the alias "this", which is the alias NHibernate automatically assigns to the root entity (table) in the query, but it's the only way I've found to reference the key of the parent query's table from within the sub-query.

我乃一代侩神 2024-08-18 17:46:33

我弄清楚了如何使用 IsNotEmpty 表达式来做到这一点。这里使用 NHibernate Lambda 扩展:

Session.CreateCriteria<FooBar>()
    .Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
    .List<FooBar>();

I worked out how to do this using the IsNotEmpty expression. Here it is using NHibernate Lambda Extensions:

Session.CreateCriteria<FooBar>()
    .Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
    .List<FooBar>();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文