修改 Lambda 表达式
我正在使用 NHibernate 3.0 开发一个应用程序。我开发了一个存储库,它接受表达式来使用 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);
}
我的疑问是:
这可能吗?必要时添加一些条件(当我的参数有价值时)?
谢谢
/// 我的编辑
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);
I'm developing an application with NHibernate 3.0. I have developed a Repository hat accept a expression to do some filter with QueryOver. My method is something like this:
public IEnumerable<T> FindAll(Expression<Func<T, bool>> filter) {
return Session.QueryOver<T>().Where(filter).List();
}
It works fine. So, I have a Service layer as well, and My methods in this services accepts primitives types, like this:
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);
}
My doubts are:
Is it possible ? Ta add some conditions when necessary (when my parameters has value) ?
Thanks
/// my edits
public ActionResult Index(ProductFilter filter) {
if (!string.IsNullOrEmpty(filter.Name) {
return View(_service.GetProductsByName(filter.Name))
}
// others conditions
}
/// Almost a solution
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);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是一种方法来做到这一点。我不会对你正在做的事情进行编辑 - 它看起来像是通过示例查询,这几乎总是有问题的。这是这里其他人最好避免的。不过这个表达方式很有趣——所以我认为值得一试。
我们想像这样查询它:
所以你所要做的就是编写
RemoveCloture();
- 这不是问题。}
Here is a way to do this. I am not going to editorialize on what you are doing - it looks like query by example, which is almost always problematic. It is as the others here have best avoided. The expression thing is interesting though - so I thought it was worth a crack at it.
And we want to query it like this:
So all you have to do is write
RemoveCloture();
- not a problem.}
首先,我会通过首先避免它来解决你的问题。我对此有不同的方法。
这些都可以通过 lambda 表达式轻松实现。例如:
等等。
其次,是的,你想做的事情是可能的,但这不是我解决问题的方式。
First, I'd solve your problem by avoiding it in the first place. I'd have different methods for this.
These all have trivially easy implementations in terms of a lambda expression. For example:
etc.
Second, yes what you want to do is possible but it's not the way I'd solve the problem.
您的存储库方法定义建议您将 FindAll 视为传递条件并返回完整结果的内容。为什么不直接让结果为 IQueryable 类型并返回 Session.QueryOver?
然后,您的服务层将执行类似的操作,将“wheres”链接在一起:
Your repository method definition suggests that you see FindAll as something that you pass criteria in and get a completed result back. Why not instead just have the result be of type IQueryable and return Session.QueryOver?
Your service layer would then do something like this, chaining together the "wheres":
所以这就是你如何将 lambda 结合在一起 - 它借用了 的大部分代码desco 的这个很棒的答案值得投赞成票。
然后
调用代码就很简单了
......
So here is how you could actually and lambdas together - it borrows most of it's code from this awesome answer from desco that deserves an up-vote.
}
Then calling the code is quite simple ....
...