C# NHibernate Linq.Contains代码生成有bug吗?
我正在努力实现:C# NHibernate Linq.Contains代码生成有bug吗?,c#,.net,nhibernate,linq-to-nhibernate,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 {
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;
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>();
当然看起来像个bug,但我认为你把整个查询复杂化了。据我所知,你希望所有的商店都有一个叫史蒂夫·乔布斯的员工在工资单上。尝试:
var q = from s in session.Query<Store>()
where s.Staff.Any(e=>e.EmployeeName == "Steve Jobs")
这将生成您想要的查询,并且它比子查询更干净、更可读。我在本文中回答了一个类似的问题。我们可以稍微调整子查询,而不是使用Contains操作符,并使用任意操作符
很酷,我应该想到这一点,我以前在SQL中使用过任何方法,或者可能我在一个非常Linq-y的方法中尝试了太多,并且受此启发,尽可能避免使用lambda和扩展方法。但在这种情况下,.Any看起来比纯Linq方法更优雅,并且不是所有SQL概念都可以用Linq语法捕获,扩展方法是有保证的,.Distinct出现在我的脑海中,但是,我希望Linq NHibernate团队能够修复这个bug。Linq链接不仅整洁,还促进了代码重用
var q = from s in session.Query<Store>()
where s.Staff.Any(e=>e.EmployeeName == "Steve Jobs")