SingleOrDefault的动态Lambda表达式 [英] Dynamic lambda expression for SingleOrDefault

查看:37
本文介绍了SingleOrDefault的动态Lambda表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含一组表的 DataClassesDataContext ,并且我试图仅使用表名和字段名来动态进行 lambda表达式过滤.基本上,我想为每个表查找是否已经存在具有特定ID的行.

I have a DataClassesDataContext containing a group of tables, and I am trying to do lambda expression filtering dynamically using only the name of the tables and the names of the fields. Basically I want to find for each table if a row with a specific ID already exists.

如果我提前知道表格,我会使用:

If I knew the table ahead of time, I would use :

if (dataClassesDataContext.MYTABLEXs.SingleOrDefault(m => m.MYTABLEX_ID == MyId)) 
    DoExists();

但是当我以动态方式获取表名MYTABLEX和MYTABLEY(以及字段名MYTABLEX_ID和MYTABLEY_ID)作为字符串时,我试图在运行时构建上述过滤器.

But as I am getting tables names MYTABLEX and MYTABLEY (and fields names MYTABLEX_ID and MYTABLEY_ID) as strings on the fly, I am trying to build the above filter at runtime.

我可以使用以下命令动态访问表:

I can access the table dynamically using :

Type tableType = Type.GetType(incommingtableName); // incommingtableName being looped over MYTABLEX, MYTABLEY , ...
var dbTable = dataClassesDataContext.GetTable(tableType);

但是后来我被困住了.我该如何构建一个lambda表达式,其行为类似于:

But then I am stuck. How can I build a lambda expression that will behave something like :

if (dbTable.SingleOrDefault(m => m.incommingtableName_id == MyId)) 
    DoExists();

有什么主意吗?

推荐答案

您可以在运行时构建表达式.而且,您还需要具有 SingleOrDefault 方法的通用版本.这是示例:

You can build an expression in runtime. And also you would need to have generic version of SingleOrDefault method. Here is example:

Type tableType = typeof (incommingtableName); // table type
string idPropertyName = "ID"; // id property name
int myId = 42; // value for searching

// here we are building lambda expression dynamically. It will be like m => m.ID = 42;
ParameterExpression param = Expression.Parameter(tableType, "m"); 
MemberExpression idProperty = Expression.PropertyOrField(param, idPropertyName);
ConstantExpression constValue = Expression.Constant(myId);

BinaryExpression body = Expression.Equal(idProperty, constValue);

var lambda = Expression.Lambda(body, param);


// then we would need to get generic method. As SingleOrDefault is generic method, we are searching for it,
// and then construct it based on tableType parameter

// in my example i've used CodeFirst context, but it shouldn't matter
SupplyDepot.DAL.SupplyDepotContext context = new SupplyDepotContext();
var dbTable = context.Set(tableType);


// here we are getting SingleOrDefault<T>(Expression) method and making it as SingleOrDefault<tableType>(Expression)
var genericSingleOrDefaultMethod =
    typeof (Queryable).GetMethods().First(m => m.Name == "SingleOrDefault" && m.GetParameters().Length == 2);
var specificSingleOrDefault = genericSingleOrDefaultMethod.MakeGenericMethod(tableType);

// and finally we are exexuting it with constructed lambda
var result = specificSingleOrDefault.Invoke(null, new object[] { dbTable, lambda });

尽可能快的优化构造的lambda可以被缓存,因此我们不需要每次都构造它,但是它应该可以相同地工作

As possible optimization constructed lambda can be cached, so we wont need to build it each time, but it should work the same

这篇关于SingleOrDefault的动态Lambda表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆