【发布时间】:2010-07-23 10:13:32
【问题描述】:
我有以下虚构的域类:
public class Pony
{
public string Name { get; set; }
public DateTime FoundDate { get; set; }
}
public class Person
{
public ICollection<Pony> Ponies { get; private set; }
public Pony NewestPony
{
get
{
return Ponies
.OrderBy(pony => pony.FoundDate)
.FirstOrDefault();
}
}
}
NewestPony 属性封装了一个域规则,该规则确定幸运者找到的最新小马。
我可以使用Enumerable 扩展方法来使用这个属性:
IEnumerable<Person> people = GetPeople();
people.Where(p => p.NewestPony != null);
这太棒了。
但是,people 是 SQL Server(在本例中为 NHibernate)的 IQueryable 外观,查询必须由查询提供程序处理并转换为 SQL。因为数据库中没有物理的“NewestPony”列,所以查询提供程序会阻塞查询。
为了解决这个问题,我可以扩展查询中的属性,将其替换为 get 实现:
IEnumerable<Person> people = GetPeople();
person.Where(p
=> p.Ponies.OrderBy(pony => pony.FoundDate).FirstOrDefault() != null);
由于查询提供程序了解 SQL Server 中的关系,它现在可以评估此查询。
此解决方案虽然可行,但确实复制了之前封装的规则。我正在寻找一种避免这种重复行为的方法,甚至可能是一种扩展查询提供程序中的属性以允许它生成正确的 SQL 语句的方法。
【问题讨论】:
-
您对该属性的映射设置是什么?因为在 NHibernate 中,如果您不映射某个属性,它将不会使用该属性为该属性生成 SQL。
-
该属性没有映射;表中没有可将其映射到的列。
-
你真的在使用 Linq to NHibernate 吗? ayende.com/Blog/archive/2009/07/26/… 和 ayende.com/Blog/archive/2007/03/17/…。如果不是,请使用 ICriteria,或更改并使用 Linq2NH。
-
我绝对在使用 LINQ to NHibernate。我不相信提供者有能力将派生成员扩展为表达式。 NHibernate 的 LINQ 提供者虽然有点偶然。我知道的所有提供商都会出现这个问题。
-
虽然我一直都在毫不费力地使用它,但我将尝试模拟一个示例来说明您的错误(因为在我的情况下分离关注点可能会模糊我的视野)。如果您碰巧有一个说明问题的小示例项目,请务必在线发布它,我会从那里拿走,我可以看看。
标签: c# linq iqueryable