gdo*_*ica 6 .net c# nhibernate asp.net-mvc entity-framework
我正在使用现在的实体框架 - 但它是所有ORM甚至IEnumerable之间"共享"的问题.
假设我在MVC中有一个方法如下:
[HttpPost]
public ActionResult Foo(FooModel model)
{
var context = new Context(); -- The EF session
var data = context.Foo.Where(???).ToList();
return View(data);
}
Run Code Online (Sandbox Code Playgroud)
我想根据输入参数查询上下文,如:
var data = context.Foo.Where(x => x.Date == model.Date &&
x.Name == model.Name &&
x.ItemCode = model.ItemCode).ToList();
Run Code Online (Sandbox Code Playgroud)
但它比这更复杂,因为如果上面的一个参数(Date\ Name\ ItemCode)为null,我不想将它包含在查询中.
如果我硬编码它可能看起来像这样:
var query = context.Foo;
if (model.Date != null)
query =query.Where(x => x.Date == model.Date);
if (model.ItemCode != null)
query =query.Where(x => x.ItemCode == model.ItemCode);
...
Run Code Online (Sandbox Code Playgroud)
必须有一种比这更简单的方法.
我需要一种方法来生成Expression<T, bool>要在Where方法中使用的类型的表达式.
[HttpPost]
public ActionResult Foo(FooModel model)
{
var context = new Context(); -- The EF session
var data = context.Foo.Where(THE_EXPRESSION).ToList();
return View(data);
}
Run Code Online (Sandbox Code Playgroud)
是否有内置的方法来构建该表达式?在nuget中有一个包吗?
更新:模型实体中可能有超过30个属性; 写30次每个查询的位置可能是一个痛苦的脖子:
.Where(model.Date != null, x => x.Date == model.Date)
.Where(model.Name != null, x => x.Name == model.Name)
.Where(model.ItemCode != null, x => x.ItemCode == model.ItemCode)
...
...
...
.ToList();
Run Code Online (Sandbox Code Playgroud)
您的硬编码方法通常是最好的方法.
但是,您可以尝试通过编写适当的扩展方法来帮助保持代码清洁,从而使您的生活更轻松.
试试这个例子:
public static class QueryableEx
{
public static IQueryable<T> Where<T>(
this IQueryable<T> @this,
bool condition,
Expression<Func<T, bool>> @where)
{
return condition ? @this.Where(@where) : @this;
}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以编写这段代码:
[HttpPost]
public ActionResult Foo(FooModel model)
{
using (var context = new Context())
{
var data = context.Foo
.Where(model.Date != null, x => x.Date == model.Date)
.Where(model.Name != null, x => x.Name == model.Name)
.Where(model.ItemCode != null, x => x.ItemCode == model.ItemCode)
.ToList();
return View(data);
}
}
Run Code Online (Sandbox Code Playgroud)
(请不要忘记处理您的上下文或用于using为您完成.)
试试吧.这是使用反射和表达式动态构建查询.我只用物体测试过它.
static IQueryable<T> Filter<T>(IQueryable<T> col, T filter)
{
foreach (var pi in typeof(T).GetProperties())
{
if (pi.GetValue(filter) != null)
{
var param = Expression.Parameter(typeof(T), "t");
var body = Expression.Equal(
Expression.PropertyOrField(param, pi.Name),
Expression.PropertyOrField(Expression.Constant(filter), pi.Name));
var lambda = Expression.Lambda<Func<T, bool>>(body, param);
col = col.Where(lambda);
}
}
return col;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1559 次 |
| 最近记录: |