LINQ:在匿名类型的Where里面使用Expression

时间:2014-03-25 19:56:17

标签: c# linq anonymous-types

目标:调用一个返回表达式的方法,我可以用它来链接匿名IQueryable上的方法。

示例:

var allProducts = from p in ctx.Products;
var customWhere = Product.GiveMeYourQuery();
var productsIWant = allProducts.Where(customWhere);
Console.Writeline("yeaaaaah!");

这就是我现在提出的,当然,这不起作用:

class MainClass
    {
        public static void Main(string[] args)
        {
            var list = new [] {
                new { Name = "ciao", Age = 18 },
                new { Name = "prova", Age = 28 },
                new { Name = "mah", Age = 38 },
                new { Name = "boh", Age = 48 }
            };

            var myAnon = list.Where(x => x.Name.Length > 2).AsQueryable();
            var thisthat = new MainClass();

            var subset = myAnon.Where(thisthat.Where);
        }

        public Expression<Func<T, bool>> Where<T>(T anon){
            var expr = Expression.Lambda(Expression.Equal(Expression.Constant(anon), Expression.Constant(anon)));

            return (Expression<Func<T, bool>>) expr;
        }
    }

编译智慧: ../Program.cs(24,24):错误CS0407:方法或委托'System.Linq.Expressions.Expression LINQInjector.MainClass.Where(匿名类型)'返回类型与委托`bool System.Func(匿名)不匹配')返回类型(CS0407)(LINQInjector)

我觉得我非常接近,但我真的看不到路径。

不幸的是我不能只将一个'对象转换为我创建的类型,因为程序应该输出的是SQL(是的,我基本上构建了一个查询构建器,它将另一层提供给要执行的查询),因为我是必须创建太多类型(每个类型为每个可能的数十个表之间的连接链)。

编辑:

虽然我感谢你试图向我展示替代方案和解决方法,但此时我认为没有。这是我的问题:如何将表达式注入匿名类型。如果不能这样做就这么说。

1 个答案:

答案 0 :(得分:1)

由于您希望在编译时访问在其创建范围之外的对象的已知属性,因此您不想使用匿名对象。如果您使用在创建anon对象的同一范围内创建的lambda访问它,则匿名对象是合适的,但您不想这样做。您希望另一个方法静态访问该对象的属性。只要给它一个名字,它就会让所有超级变得容易:

public class Foo 
{
    public string Name{get;set;} 
    //...
}

public static Expression<Func<Foo, bool>> NameEquals(string name)
{
    return foo => foo.Name == name;
}