目标:调用一个返回表达式的方法,我可以用它来链接匿名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系统。函数(匿名类型)`返回类型(CS0407) (LINQInjector)
我觉得我很接近了,但我不能真正看到路径。
不幸的是,我不能只是将a'对象转换为我创建的类型,因为程序应该输出的是SQL(是的,我基本上是构建一个querybuilder,为另一层提供查询执行),因为我必须创建太多类型(每种类型为数十个表之间的每个可能的连接链)。
编辑:
虽然我很感激你试图向我展示替代方案和解决方案,但在这一点上,我认为没有。这是我的问题:如何将表达式注入匿名类型。
由于您希望访问在创建对象的作用域之外的对象的编译时已知的属性,因此您不希望使用匿名对象。如果您使用在创建匿名对象的同一作用域中创建的lambdas访问匿名对象,那么它将是合适的,但您不希望这样做。你想让另一个方法静态地访问那个对象的属性。只要给它一个名字,它就会使所有的super变得简单:
public class Foo
{
public string Name{get;set;}
//...
}
public static Expression<Func<Foo, bool>> NameEquals(string name)
{
return foo => foo.Name == name;
}