【问题标题】:Nhibernate Disjunction ("OR") Query Across Many-To-One and Many-To-Many Relationships跨多对一和多对多关系的休眠析取(“OR”)查询
【发布时间】:2011-08-24 01:19:33
【问题描述】:

这个问题与这里的问题接近但不一样: NHibernate Query across multiple tables

基本上,我的问题给出了以下模型,我将如何查询以找出当前狗的名字是“foo”还是过去的狗的名字是“foo”(析取)。 基本上我对 CurrentDog 有一个多对一关系,对 PastDogs 有一个多对多关系。

public class Dog {
    public string name {get; set;}
}

public class Owner {
    public string firstname {get; set;}
    public string lastname {get; set;}
    public Dog CurrentDog {get; set;}
    public Dog[] PastDogs {get; set;}
}

我猜 SQL 应该是这样的:

    SELECT o.* FROM owners AS o
    INNER JOIN dogs AS cd ON o.current_dog_id = cd.id
    INNER JOIN owner_past_dog_maps AS pd ON o.id = pd.owner_id
    INNER JOIN dogs AS d ON pd.dog_id = d.id
    WHERE d.name = 'foo' 
    OR cd.name = 'foo'

希望这是有道理的...如果有人问,我会尽力澄清。

【问题讨论】:

  • 我想我可以把它放在一个新帖子中,但这个问题的扩展是我如何归还主人曾经拥有的所有狗,过去或现在?

标签: c# .net sql nhibernate


【解决方案1】:

我尝试使用 QueryOver 和别名来解决它

Owner myOwner = null;
Dog myCurrentDog = null; 
Dog myPastDogs = null;

var sax = _HibSession.QueryOver<Owner>(() => myOwner)
                .JoinAlias(() => myOwner.CurrentDog, () => myCurrentDog, JoinType.InnerJoin)
                .JoinAlias(() => myOwner.PastDogs, () => myPastDogs , JoinType.InnerJoin)
                .Where(Restrictions.Disjunction()
                    .Add(Restrictions.EqProperty(myCurrentDog.Name,"foo"))
                    .Add(Restrictions.EqProperty(myPastDogs.Name,"foo"))                    
                )                                            
                .List<Owner>();

希望对你有帮助!

【讨论】:

  • 太酷了。我猜想不同的方法......使用 QueryOver 模式有什么好处吗?
  • 我总是使用 QueryOver 模式,因为没有字符串可以放在代码中(例如 .Restrictions.Eq("cd.Name","foo") 作为 Criteria 模式)。因此,我降低了编写导致运行时错误的错误字段名称的可能性(例如 .Restrictions.Eq("cd.NaNe","foo") 仅在运行时抛出异常)。享受 QueryOver! :-)
  • 这里是它的潜力的一些例子nhforge.org/blogs/nhibernate/archive/2009/12/17/…
  • 哦,太好了。感谢您的提示!
【解决方案2】:

我想我应该从我是 NHibernate 的新手开始。我不明白的是 NHibernate 中发生的别名,并且您不是为表创建别名,而是为关系和属性名称创建别名。看哪,将返回所有拥有或曾经拥有狗名 foo 的所有者的解决方案:

    var output = Session.CreateCriteria<Owner>()
        .CreateAlias("CurrentDog", "cd")
        .CreateAlias("PastDogs", "pd")
        .Add
        (
            Restrictions.Disjunction()
            .Add(Restrictions.Eq("cd.Name", "foo"))
            .Add(Restrictions.Eq("pd.Name", "foo"))
        )
        .List<Owner>();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    • 2015-04-12
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    • 2015-12-22
    相关资源
    最近更新 更多