标签: linq-expressions

将 MethodBody 转换为表达式树

有没有办法将 MethodBody(或其他反射技术)转换为 System.Linq.Expressions.Expression 树?

.net-4.0 linq-expressions

5
推荐指数
1
解决办法
464
查看次数

如何在不编译的情况下从现有的LambdaExpression构建LambdaExpression

我想结合两个LambdaExpressions而不编译它们.

这就是我编译它们时的样子:

    public Expression<Func<TContainer,bool>> CreatePredicate<TContainer,TMember>(
        Expression<Func<TContainer,TMember>> getMemberExpression, 
        Expression<Func<TMember,bool>> memberPredicateExpression)
    {
        return x => memberPredicateExpression.Compile()(getMemberExpression.Compile()(x));
    }
Run Code Online (Sandbox Code Playgroud)

这显然不是从提供的参数中获取目标表达式的最快方法.此外,它使它与不支持C#方法调用的LINQ to SQL等查询提供程序不兼容.

从我所看到的,似乎最好的方法是建立一个ExpressionVisitor班级.然而,这似乎是一个非常常见的任务.有谁知道现有的开源代码库提供这种功能?如果没有,最好的方法ExpressionVisitor是尽可能使其尽可能通用?

c# linq expression linq-expressions expressionvisitor

5
推荐指数
1
解决办法
659
查看次数

Linq - 从表达式<T2>创建表达式<T1>

我有一个谓词 Expression<Func<T1, bool>>

我需要使用它作为谓词Expression<Func<T2, bool>>使用我试图考虑几个approches 的T1属性T2,可能使用Expression.Invoke但couln; t让我的头围绕它.

以供参考:

class T2 {
  public T1 T1;
}
Run Code Online (Sandbox Code Playgroud)

Expression<Func<T1, bool>> ConvertPredicates(Expression<Func<T2, bool>> predicate) {
  //what to do here...
}
Run Code Online (Sandbox Code Playgroud)

非常感谢提前.

c# linq predicate linq-expressions

5
推荐指数
1
解决办法
225
查看次数

EF orderby/thenby combo扩展方法

我希望能够应用firstby / thenby如下的组合排序:

allOrders().sort(s => s.ProductName, s => s.OrderDate)
Run Code Online (Sandbox Code Playgroud)

所以使用这篇文章作为灵感,我写了这个扩展方法,编译很好:

public static IQueryable<T> sort<T>(this IQueryable<T> entities, params 
  Expression<Func<T, object>>[] predicates) where T : class 
{
  var sorted = entities.OrderBy(predicates[0]);
  for (int i = 1; i < predicates.Length; i++)
    sorted = sorted.ThenBy(predicates[i]);

  return sorted;
}
Run Code Online (Sandbox Code Playgroud)

我也试过这个succint版本,它也编译:

public static IQueryable<T> sort<T>(this IQueryable<T> entities, params 
  Expression<Func<T, object>>[] predicates) where T : class
{
  return predicates.Skip(1).Aggregate(
    entities.OrderBy(predicates[0]),
    (aggregate, currentPredicate) => aggregate.ThenBy(currentPredicate));
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试按a排序DateTime,我会得到以下异常:

无法将类型"System.DateTime"强制转换为"System.Object"类型.LINQ to Entities仅支持转换EDM原语或枚举类型.

我究竟做错了什么?我正在使用EF5.

c# linq linq-to-entities entity-framework linq-expressions

5
推荐指数
1
解决办法
1296
查看次数

如何只比较日期部分和linq表达式?

我只想为网格视图制作列过滤器.简单我只想用一些额外的东西过滤网格视图列.在这里,我创建了一个返回可查询结果的IQueryable.

这是我的代码:

- - - - - - - - - - - - - - - - - - - - - 更新 - - - - -----------------------------------------

public static IQueryable<T> FilterForColumn<T>(this IQueryable<T> queryable, string colName, string searchText)
{
    if (colName != null && searchText != null)
    {
        var parameter = Expression.Parameter(typeof(T), "m");
        var propertyExpression = Expression.Property(parameter, colName);
        System.Linq.Expressions.ConstantExpression searchExpression = null;
        System.Reflection.MethodInfo containsMethod = null;
        System.Linq.Expressions.MethodCallExpression body = null;
        System.Nullable<DateTime> nextDate = null;
        Expression ex1 = null;
        Expression …
Run Code Online (Sandbox Code Playgroud)

linq linq-expressions

5
推荐指数
1
解决办法
3615
查看次数

包含的LINQ表达式

我想在linq中添加动态表达式,但面对包含方法的问题,它对Equal方法非常有效

问题是我正在FilterField动态地如何在查询中替换

到目前为止,我曾尝试过

List<int> Ids = new List<int>();  
**string filterField ="DEPARTMENT"; ==> Dynamic Field**

var eParam = Expression.Parameter(typeof(EmployeeDetail), "e");

var comparison = Expression.Equal(Expression.Property(eParam, filterField), Expression.Convert(Expression.Constant(Ids), Expression.Property(eParam, filterField).Type));

var lambda = Expression.Lambda<Func<EmployeeDetail, bool>>(comparison, eParam);

var countMonthly1 = ctx.tblMonthlyInput.Join(ctx.tblEmployee, a => a.CompanyId, b => b.CompanyId, (a, b) => b).Where(lambda).Count();
Run Code Online (Sandbox Code Playgroud)

我想使用linq表达式使上述查询适用于Contains方法

示例查询:

var countMonthly = (from a in ctx.tblMonthlyInput
                    join b in ctx.tblEmployee on a.CompanyId equals b.CompanyId
                    where categoryId.Contains(a.CategoryId)  //want to make this dynamic
                    select a).Count() == 0;
Run Code Online (Sandbox Code Playgroud)

c# linq asp.net-mvc linq-expressions

5
推荐指数
1
解决办法
4858
查看次数

Queryable.Aggregate不使用空值

我正在写一个转换IQueryable查询的访问者.它使用Aggregate种子方法,null然后使用一些函数来转换它.我的问题是这个null是类型的decimal?.但我得到一个例外

'Expression of type 'System.Object' cannot be used for parameter of type 
'System.Nullable`1[System.Decimal]' of method 'System.Nullable`1[System.Decimal] 
Aggregate[Nullable`1,Nullable`1]
(System.Linq.IQueryable`1[System.Nullable`1[System.Decimal]], 
System.Nullable`1[System.Decimal], 
System.Linq.Expressions.Expression`1[System.Func`3[System.Nullable`1[System.Decimal],
System.Nullable`1[System.Decimal],System.Nullable`1[System.Decimal]]])''
Run Code Online (Sandbox Code Playgroud)

经过一些研究后,我发现它Aggregate本身就在破坏我的查询:

public static TAccumulate Aggregate<TSource,TAccumulate>(this IQueryable<TSource> source, TAccumulate seed, Expression<Func<TAccumulate,TSource,TAccumulate>> func) {
    if (source == null)
        throw Error.ArgumentNull("source");
    if (func == null)
        throw Error.ArgumentNull("func");
    return source.Provider.Execute<TAccumulate>(
        Expression.Call(
            null,
            GetMethodInfo(Queryable.Aggregate, source, seed, func),
            new Expression[] { source.Expression, Expression.Constant(seed), Expression.Quote(func) }
            ));
}
Run Code Online (Sandbox Code Playgroud)

我的问题是与Expression.Constant(seed)这是nullExpression.Constant它转换为对象的类型恒定:

public …
Run Code Online (Sandbox Code Playgroud)

.net c# linq iqueryable linq-expressions

5
推荐指数
1
解决办法
499
查看次数

如何在lambda表达式中设置断点?

我想调试在表达式树中调用的lambda.不幸的是,断点永远不会被击中.

这是一个完整的控制台程序:

private static void Main()
{
    var evalAndWrite = EvalAndWrite(x => x + 1 /* a breakpoint here is never hit */);
    evalAndWrite(1);
    Console.ReadLine();
}

private static Action<int> EvalAndWrite(Expression<Func<int, int>> expr)
{
    var result = Expression.Variable(typeof(int), "result");
    var assign = Expression.Assign(result, expr.Body);
    var writeLine = Expression.Call(typeof(Console), nameof(Console.WriteLine), null, result);
    var body = Expression.Block(new[] {result}, assign, writeLine);
    return Expression.Lambda<Action<int>>(body, expr.Parameters[0]).Compile();
}
Run Code Online (Sandbox Code Playgroud)

如果我 lambda中设置一个断点(即x + 1使用F9),整条线在实际执行时会被拉断而不是lambda.

看看body我看到的调试视图:

.Block(System.Int32 $result) {
    $result = $x + 1;
    .Call …
Run Code Online (Sandbox Code Playgroud)

c# linq-expressions

5
推荐指数
1
解决办法
1652
查看次数

通过动态创建linq查询在c#中为sql等效项创建linq表达式,用于sql等效项

我有一个具有以下架构的表:

  create table test 
  (
    foo1 nvarchar(4),
    foo2 nvarchar(30)
  )
  create unique index test_foo1 on test (foo1);
Run Code Online (Sandbox Code Playgroud)

当使用EF使用Entity创建实体时,它会生成类似以下的类:

public class Test
{
  public string foo1 {get; set;}
  public string foo2 {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

因此,在编辑此记录时,我将像下面那样构建动态表达式树,以查找是否存在用于实际编辑的数据库记录:

Expression combinedExpression = null;

            foreach (string propertyName in keyColumnNames)
            {
               var propertyInfo = typeof(Entity).GetProperty(propertyName);
               var value = propertyInfo.GetValue(entityWithKeyFieldsPopulated);
               var type = propertyInfo.PropertyType;


                Expression e1 = Expression.Property(pe, propertyName);
                Expression e2 = Expression.Constant(value, type);
                Expression e3 = Expression.Equal(e1, e2);

                if (combinedExpression == null)
                {
                    combinedExpression = e3;
                } …
Run Code Online (Sandbox Code Playgroud)

c# sql linq linq-expressions

5
推荐指数
1
解决办法
134
查看次数

如何在.NET中创建表达式构建器

我已经编写了一些代码来允许在我们的网站上过滤产品,而且我的代码味道非常糟糕.用户可以选择1-*这些过滤器,这意味着我需要特定于该WHERE子句.

我想我正在寻找一种构建lambda表达式的方法,所以对于每个过滤器我都可以"修改"我的WHERE子句 - 但我不确定如何在.NET中执行此操作,并且必须有一种方法.

处于当前状态的代码(实际上是硬编码的,而不是动态的,添加更多过滤器选项会很麻烦).

public static class AgeGroups
{
    public static Dictionary<string, int> Items = new Dictionary<string, int>(){
        { "Modern (Less than 10 years old)", 1 },
        { "Retro (10 - 20 years old)", 2 },
        { "Vintage(20 - 70 years old)", 3 },
        { "Antique(70+ years old)", 4 }
    };

    public static IQueryable<ProductDTO> FilterAgeByGroup(IQueryable<ProductDTO> query, List<string> filters)
    {
        var values = new List<int>();
        var currentYear = DateTime.UtcNow.Year;
        foreach (var key in filters)
        {
            var …
Run Code Online (Sandbox Code Playgroud)

.net c# linq iqueryable linq-expressions

5
推荐指数
1
解决办法
292
查看次数