为LINQ查询构建具有表达式树的Any()

时间:2018-05-27 10:12:54

标签: c# linq expression-trees

我正在构建一个SQL" Any"使用System.Linq.Expressions.Expression类动态子句

我可以这样做

Expression<Func<User, Lead, bool>> predicate = (user, lead) => user.UserRoleSubProducts.Any(x => x.SubProductID == lead.SubProductID);

但我无法使用Expression Tree实现这一目标。

我在下面试过

var param1 = Expression.Parameter(typeof(User), "user");
var property1 = Expression.Property(param1, "UserRoleSubProducts");
var exp1 = Expression.Lambda(property1, new[] { param1 });

var param2 = Expression.Parameter(typeof(Lead), "lead");
var property2 = Expression.Property(param2, "SubProductID");
var exp2 = Expression.Lambda(property2, new[] { param2 });

var param3 = Expression.Parameter(property1.Type.GetProperty("Item").PropertyType, "x");
var property3 = Expression.Property(param3, "SubProductID");
var exp3 = Expression.Lambda(property3, new[] { param3 });

var equality = Expression.Equal(property2, property3);

var any = typeof(Queryable).GetMethods().Where(m => m.Name == "Any").Single(m => m.GetParameters().Length == 2).MakeGenericMethod(property1.Type);

var expression = Expression.Call(null, any, property1, equality);

但是

  

类型的表达   &#39; {Microsoft.OData.Client.DataServiceCollection {1}} 1 [Microsoft.OData.Client.DataServiceCollection 1[Api.Models.UserRoleSubProduct]' cannot be used for parameter of type System.Linq.IQueryable 1](System.Linq.IQueryable 1[Api.Models.UserRoleSubProduct]]' of method 'Boolean Any[DataServiceCollection 1 [Api.Models.UserRoleSubProduct ]]   System.Linq.Expressions.Expression 1[Microsoft.OData.Client.DataServiceCollection 2 [Microsoft.OData.Client.DataServiceCollection`1 [Api.Models.UserRoleSubProduct],System.Boolean]])&#39;

我认为我足够接近。任何帮助表示赞赏

1 个答案:

答案 0 :(得分:4)

忽略冗余的未使用的lambda表达式,问题在于最后两行。

首先,您使用了错误的泛型类型(public class Main2Activity extends AppCompatActivity { List<Aliment> lstAlim=new ArrayList<Aliment>(); DbHelper dbHelper; Button btnAfiseazaLista; LinearLayout container; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); btnAfiseazaLista=(Button) findViewById(R.id.btnAfiseazaLista); container=(LinearLayout)findViewById(R.id.container); dbHelper=new DbHelper(getApplicationContext()); dbHelper.createDataBase(); btnAfiseazaLista.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { lstAlim=dbHelper.getAllAlim(); for(Aliment aliment:lstAlim){ LayoutInflater inflater=(LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); View addView=inflater.inflate(R.layout.row,null); TextView txtAliment=(TextView)addView.findViewById(R.id.txtAliment); TextView txtCalorii=(TextView)addView.findViewById(R.id.txtCalorii); TextView txtCantitate=(TextView)addView.findViewById(R.id.txtCantitate); txtAliment.setText(aliment.getAliment()); txtCalorii.setText(aliment.getCalorii()); txtCantitate.setText(aliment.getCantitate()); container.addView(addView); } } }); } }),而正确的类型基本上是参数iOS的类型

Shared

=&GT;

iOS

映射到代码中的MakeGenericMethod(property1.Type)

其次,x的第二个参数必须是lambda表达式(不仅仅是代码中的.Any(x => x.SubProductID == lead.SubProductID) )。

第三,由于.Any<T>((T x) => ...) 很可能是一种集合类型,因此您应该调用param3.Type而不是Any

equality方法有overload,非常方便&#34;调用&#34;静态通用扩展方法:

user.UserRoleSubProducts

所以最后两行可以替换为:

Enumerable.Any