我想在linq lambda的子句中使用方法
中传递的参数替换operator(==,> =,> ...)方法:
public IEnumerable<Localisation> GetByFiltre(string filter, string valeurDate1)
/*
filter has the value of an operator:
>
==
!=
>=
<=
*/
DateTime dt = Convert.ToDateTime(valeurDate1);
var mod = from o in new GpsContext().Locals.Where(loc => loc.Date == dt)
我想在带有参数过滤器的子句中替换== 获得这样的东西
var mod = from o in new GpsContext().Locals.Where(loc => loc.Date filter dt)
任何人都知道如何使它发挥作用?
答案 0 :(得分:3)
我认为最好用字符串过滤器和相应的代表制作字典。
class YourClass
{
static readonly Dictionary<string, Func<DateTime, DateTime, bool>> s_filters = new Dictionary<string, Func<DateTime, DateTime, bool>>
{
{ ">", new Func<DateTime, DateTime, bool>((d1, d2) => d1 > d2) }
{ "==", new Func<DateTime, DateTime, bool>((d1, d2) => d1 == d2) }
{ "!=", new Func<DateTime, DateTime, bool>((d1, d2) => d1 != d2) }
{ ">=", new Func<DateTime, DateTime, bool>((d1, d2) => d1 >= d2) }
{ "<=", new Func<DateTime, DateTime, bool>((d1, d2) => d1 <= d2) }
};
public IEnumerable<Localisation> GetByFiltre(string filter, string valeurDate1)
{
...
DateTime dt = Convert.ToDateTime(valeurDate1);
var filterDelegate = s_filters[filter];
var mod = from o in new GpsContext().Locals.Where(loc => filterDelegate(loc.Date,dt));
...
}
}
答案 1 :(得分:1)
有一个很好的库可以将字符串解析为此处描述的Lamdba表达式
可在此处下载
http://msdn2.microsoft.com/en-us/vcsharp/bb894665.aspx
它具有非常好的表达式语法,可以让您表达相当多的不同查询和操作。
请注意,根据查询,您可能会失去某些类型的安全性。在操作正常的情况下,编译器无法推断出从字符串中解析Select lambda的任何类型的投影。这种情况最终会导致非通用的IQueryables,而不是一般类型的IQueryables。有时这是可以的,但它确实阻止您稍后在查询中使用通用扩展方法。
编辑以阐明非通用查询操作的情况:该库包含一组非泛型版本的查询扩展方法,这些方法采用表达式的字符串表示形式并在非泛型IQueryable上运行。如果您查看代码,如果您想要的那个代码不存在,很容易看到如何编写这些代码。例如,我需要做一个非泛型加入,它只花了几个小时。
答案 2 :(得分:1)
我发现问题的解决方案是这样的:
var test = dataContext.Interactions.DynamicWhere<Interaction,DateTime>("Created_Month", ExpressionType.LessThan, DateTime.Now);
您可以使用任何ExpressionType
- 等于,小于,大于等等,如果可能,它将被转换为T-SQL(因此过滤将在服务器上完成)。它也可以在IEnumerables
内存。
以下是代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace WindowsFormsApplication1
{
public static class GenericFilterExtension
{
public static IQueryable<TRow> DynamicWhere<TRow,TColumn>(this IQueryable<TRow> input, string field, ExpressionType binaryOperator, TColumn value)
{
var exp = MakeWhereLambda<TRow, TColumn>(field, binaryOperator, value) as Expression<Func<TRow, bool>>;
return input.Where(exp);
}
public static IEnumerable<TRow> DynamicWhere<TRow, TColumn>(this IEnumerable<TRow> input, string field, ExpressionType binaryOperator, TColumn value)
{
var exp = MakeWhereLambda<TRow, TColumn>(field, binaryOperator, value).Compile() as Func<TRow, bool>;
return input.Where(exp);
}
private static LambdaExpression MakeWhereLambda<TRow, TColumn>(string field, ExpressionType binaryOperator, TColumn value)
{
var param = Expression.Parameter(typeof(TRow), "n");
var op = Expression.MakeBinary(binaryOperator, Expression.Property(param, field), Expression.Constant(value));
return Expression.Lambda(op, new ParameterExpression[] { param });
}
}
}
答案 3 :(得分:0)
你可以传入你的where子句的功能,例如
public IEnumerable<Localisation> GetByFiltre(Func<IEnumerable<localisation>, IEnumerable<localisation>> whereClause)
{
/*
filter has the value of an operator:
>
==
!=
>=
<=
*/
DateTime dt = Convert.ToDateTime(valeurDate1);
var mod = whereClause(new GpsContext().Locals);
}
并将其命名为:
GetByFiltre(f => f.Where(d => d.Date > SomeDate));
答案 4 :(得分:-1)
过滤器应包含“==”,“&gt; =”等?您可以用传统方式分析过滤字符串:
var mod = from o in new GpsContext().Locals.Where(loc =>
{
switch(filter)
{
case "==":
return loc.Date == dt;
case ">=":
return loc.Date >= dt;
// ...
}
})