【发布时间】:2011-01-20 16:13:49
【问题描述】:
我正在使用 NHibernate 3.0 开发应用程序。我已经开发了一个 Repository hat 接受一个表达式来使用 QueryOver 进行一些过滤。我的方法是这样的:
public IEnumerable<T> FindAll(Expression<Func<T, bool>> filter) {
return Session.QueryOver<T>().Where(filter).List();
}
它工作正常。所以,我也有一个服务层,我在这个服务中的方法接受原始类型,如下所示:
public IEnumerable<Product> GetProducts(string name, int? stock, int? reserved) {
// how init the expression ?
Expression<Func<Product, bool>> expression = ???;
if (!string.IsNullOrEmpty(name)) {
//add AND condition for name field in expression
}
if (stock.HasValue) {
//add AND condition for stock field in expression
}
if (reserved.HasValue) {
//add AND condition for reserved field in expression
}
return _repository.FindAll(expression);
}
我的疑惑是:
有可能吗? Ta在必要时添加一些条件(当我的参数有值时)?
谢谢
/// 我的编辑
public ActionResult Index(ProductFilter filter) {
if (!string.IsNullOrEmpty(filter.Name) {
return View(_service.GetProductsByName(filter.Name))
}
// others conditions
}
/// 几乎是一个解决方案
Expression<Func<Product, bool>> filter = x => true;
if (!string.IsNullOrEmpty(name))
filter = x => filter.Compile().Invoke(x) && x.Name == name;
if (stock.HasValue)
filter = x => filter.Compile().Invoke(x) && x.Stock == stock.Value;
if (reserved.HasValue)
filter = x => filter.Compile().Invoke(x) && x.Reserved == reserved.Value;
return _repository.FindAll(filter);
【问题讨论】:
-
我知道一种方法可以做到这一点 - 但我需要一点时间来实施。但是您可以只做一个
x=>(!string.IsNullOrEmpty(name)||name==x.Name)&&(stock.HasValue||x.Stock==stock??0) ... etc我可以为您添加的是一种用常量替换 cloture 的方法,然后简化逻辑评估,以便表达式最终尽可能短。 -
嗨,尼尔,如果可以的话,如果你能帮助我,我想看看一些代码 =D。我想象过你说的这种方式,我会研究这种可能性。谢谢!
-
@Felipe 看看我的回答 - 你去吧。
-
好的,我认为您提出的解决方案会有问题。问题是一旦你调用 Compile() 和 Invoke() 你就会失去 nhibernate 依赖的元数据来构建查询。本质上,您将获得只能在客户端上评估的东西,而不是可以转换为 SQL 的东西。
-
谢谢尼尔,我会选择你的解决方案。谢谢=D
标签: c# linq nhibernate lambda expression