目标:调用一个返回表达式的方法,我可以用它来链接匿名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(是的,我基本上构建了一个查询构建器,它将另一层提供给要执行的查询),因为我是必须创建太多类型(每个类型为每个可能的数十个表之间的连接链)。
虽然我感谢你试图向我展示替代方案和解决方法,但此时我认为没有。这是我的问题:如何将表达式注入匿名类型。如果不能这样做就这么说。
答案 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;
}