NHibernate Linq。包含代码生成有错误吗?

时间:2010-12-08 17:20:58

标签: c# .net nhibernate linq-to-nhibernate

我正在努力实现:

select StoreId, StoreName from Store where StoreId in (
     select StoreId from Employee where EmployeeName = 'Steve Jobs')

我有这段代码:

public class Store
{
  public virtual int StoreId { get; private set; }
  public virtual string StoreName { get; set; }

  public virtual IList<Employee> Staff { get; set; }
}

public class Employee
{
  public virtual Store Store { get; set; }

  public virtual int EmployeeId { get; private set; }
  public virtual string EmployeeName { get; set; }
}



var q = from s in session.Query<Store>()
        where 
            (from e in session.Query<Employee>()
            where s.EmployeeName == "Steve Jobs"
            select e.Store.StoreId).Contains(s.StoreId)
        select s;

NHibernate生成这个(删除了别名):

    select s.StoreId, s.StoreName
    from Store s
    where exists
        (
            select t.StoreId
            from Employee e
            left join Store t on t.StoreId = e.StoreId
            where e.EmployeeName = 'Steve Jobs'

                -- wrongly generated code
                and t.EmployeeId = s.StoreId 

        )

Linq-toSql正确生成代码:

    select s.StoreId, s.StoreName
    from Store s
    where exists
        (
            select null
            from Employee e
            where e.EmployeeName = 'Steve Jobs'                        
                and e.StoreId = s.StoreId 

        )

在Linq到NHibernate上生成子查询代码是否有问题?

然而,HQL有效:

var q = session.CreateQuery("from Store as s where s.StoreId in (select e.WorkingInStore.StoreId from Employee as e where e.EmployeeName = 'lennon')").List<Store>();

2 个答案:

答案 0 :(得分:6)

当然看起来像一个bug,但我认为你的整个查询过于复杂。据我了解,您希望所有名为史蒂夫乔布斯的员工都在工资单上的商店。尝试:

var q = from s in session.Query<Store>()
        where s.Staff.Any(e=>e.EmployeeName == "Steve Jobs")

这应该生成您想要的查询,并且它比子查询更清晰,更易读。

答案 1 :(得分:0)

我在这篇文章中回答了类似的问题。我们可以稍微调整子查询,而不是使用Contains()运算符,而是使用Any()运算符。

LINQ to NHibernate WHERE EXISTS IN