假设我有一个课程凭证:
public class Voucher
{
public Guid Id {get;set;}
public DateTime DateAvailable {get;set;}
}
和一个类条目
public class Entry
{
public Guid Id {get;set;}
public Voucher Voucher {get;set;}
// ... other unrelated properties
}
如何创建NHibernate Criteria查询,以查找当前未分配给条目的第一个可用凭证?
等效的SQL将是
select
v.Id, v.DateAvailable
from
Voucher v
left join Entries e on e.VoucherId = v.Id
where
v.DateAvailable <= getutcdate() and
e.Id is null
编辑:我仍然无法解决这个问题。凭证表没有对条目表的引用,但我需要找到尚未分配给条目的第一个凭证(按日期顺序)。这看起来像是一个简单的任务,但是我一直在阅读关于使用NHibernate标准的所有内容左连接都要求Voucher对象具有引用该条目的属性。当然有一种方法可以反转查询或向Voucher对象添加引用属性,而无需修改数据库以使每个表引用另一个。
编辑2:对于它的价值,我认为没有一些修改就可以做我想做的事情。我最终得到了一个查询,使用Entry作为主要标准,将凭证作为子标准,但随后UniqueResult返回null,即使数据存在。我想它只是无法建立关联。
如果有人遇到这种情况,我最终在每个表中引用另一个外键并使用References&lt;&gt;映射以关联两者。这不是主意,因为我必须手动将每个实体的子属性设置为另一个以使关联双向,但它至少可以在没有大量更改的情况下工作。
答案 0 :(得分:1)
以下内容应该可以使用HQL:
IQuery query = session.CreateQuery(@"
FROM
Voucher v LEFT JOIN
Entry e
WHERE
e.ID IS NULL AND
v.DateAvailable <= :now
");
query.SetParameter("now", DateTime.Now);
// If you want to restrict to only the first result
query.SetMaxResults(1);
Voucher v = query.UniqueResult<Voucher>();
// Otherwise, get a list of results...
// List<Entry> results = query.List<Entry>();
答案 1 :(得分:1)
按字面翻译SQL:
var voucher = NHibernateSessionManager.Session.CreateCriteria<Voucher>("v")
.Add(Restrictions.Le("v.DateAvailable", DateTime.UtcNow))
.CreateCriteria("Entries", "e")
.Add(Restrictions.IsNull("e.Id"))
.SetMaxResults(1)
.UniqueResult<Voucher>();
现在,如果我理解正确,可能会有一些改变。 如果声明:“..查找当前未分配给条目的第一个可用凭证...”与法规“查找没有条目的第一个可用凭证...”相同(因为凭证是有许多条目的实体......根据你的类)然后你可以这样做:
var voucher = NHibernateSessionManager.Session.CreateCriteria<Voucher>()
.Add(Restrictions.IsEmpty("Entries"))
.Add(Restrictions.Le("DateAvailable", DateTime.UtcNow))
.SetMaxResults(1)
.UniqueResult<Voucher>();
...假设您已在凭证实体中映射了Entries属性。
但也许我弄错了......
答案 2 :(得分:0)
从记忆中,可能不起作用:
session.CreateQuery<Entry>().CreateAlias("Voucher","v").Add(Restrictions.And(
Restrictions.Lt("DateAvailable",DateTime.Now),
Restrictions.Eq("v.Id",null")
).List<Voucher>();