C# SingleOrDefault的动态lambda表达式

C# SingleOrDefault的动态lambda表达式,c#,linq,lambda,linq-expressions,C#,Linq,Lambda,Linq Expressions,我有一个包含一组表的DataClassesDataContext,我正在尝试只使用表名和字段名进行lambda expression动态筛选。基本上,我想为每个表查找是否已经存在具有特定ID的行 如果我提前知道表格,我会使用: if (dataClassesDataContext.MYTABLEXs.SingleOrDefault(m => m.MYTABLEX_ID == MyId)) DoExists(); 但当我将表名MYTABLEX和MYTABLEY(以及字段名MYTA

我有一个包含一组表的
DataClassesDataContext
,我正在尝试只使用表名和字段名进行
lambda expression
动态筛选。基本上,我想为每个表查找是否已经存在具有特定ID的行

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

if (dataClassesDataContext.MYTABLEXs.SingleOrDefault(m => m.MYTABLEX_ID == MyId)) 
    DoExists();
但当我将表名MYTABLEX和MYTABLEY(以及字段名MYTABLEX_ID和MYTABLEY_ID)动态地作为字符串时,我尝试在运行时构建上述过滤器

我可以使用以下工具动态访问该表:

Type tableType = Type.GetType(incommingtableName); // incommingtableName being looped over MYTABLEX, MYTABLEY , ...
var dbTable = dataClassesDataContext.GetTable(tableType);
但是我被卡住了。我如何构建一个lambda表达式,其行为类似于:

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

有什么想法吗?

您可以在运行时构建表达式。您还需要有
SingleOrDefault
方法的通用版本。下面是一个例子:

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 });
Type tableType=typeof(incommingtableName);//肉用
字符串idPropertyName=“ID”;//id属性名
int myId=42;//搜索价值
//这里我们动态地构建lambda表达式。它将类似于m=>m.ID=42;
ParameterExpression param=表达式.参数(表类型,“m”);
MemberExpression idProperty=Expression.PropertyOrField(参数,idPropertyName);
ConstantExpression constValue=表达式常数(myId);
BinaryExpression body=表达式.Equal(idProperty,constValue);
var lambda=表达式.lambda(body,param);
//然后我们需要得到泛型方法。由于SingleOrDefault是通用方法,我们正在搜索它,
//然后基于tableType参数进行构造
//在我的示例中,我使用了CodeFirst上下文,但这并不重要
SupplyDepot.DAL.SupplyDepotContext上下文=新的SupplyDepotContext();
var dbTable=context.Set(tableType);
//在这里,我们得到SingleOrDefault(表达式)方法,并将其设置为SingleOrDefault(表达式)
var genericSingleOrDefaultMethod=
typeof(Queryable).GetMethods().First(m=>m.Name==“SingleOrDefault”&&m.GetParameters().Length==2);
var specificSingleOrDefault=genericSingleOrDefaultMethod.MakeGenericMethod(tableType);
//最后,我们用构造的lambda来解释它
var result=specificsinglerdefault.Invoke(null,新对象[]{dbTable,lambda});

尽可能地优化构造的lambda可以缓存,因此我们不需要每次都构建它,但它的工作原理应该与您可以在运行时构建表达式的工作原理相同。您还需要有
SingleOrDefault
方法的通用版本。下面是一个例子:

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 });
Type tableType=typeof(incommingtableName);//肉用
字符串idPropertyName=“ID”;//id属性名
int myId=42;//搜索价值
//这里我们动态地构建lambda表达式。它将类似于m=>m.ID=42;
ParameterExpression param=表达式.参数(表类型,“m”);
MemberExpression idProperty=Expression.PropertyOrField(参数,idPropertyName);
ConstantExpression constValue=表达式常数(myId);
BinaryExpression body=表达式.Equal(idProperty,constValue);
var lambda=表达式.lambda(body,param);
//然后我们需要得到泛型方法。由于SingleOrDefault是通用方法,我们正在搜索它,
//然后基于tableType参数进行构造
//在我的示例中,我使用了CodeFirst上下文,但这并不重要
SupplyDepot.DAL.SupplyDepotContext上下文=新的SupplyDepotContext();
var dbTable=context.Set(tableType);
//在这里,我们得到SingleOrDefault(表达式)方法,并将其设置为SingleOrDefault(表达式)
var genericSingleOrDefaultMethod=
typeof(Queryable).GetMethods().First(m=>m.Name==“SingleOrDefault”&&m.GetParameters().Length==2);
var specificSingleOrDefault=genericSingleOrDefaultMethod.MakeGenericMethod(tableType);
//最后,我们用构造的lambda来解释它
var result=specificsinglerdefault.Invoke(null,新对象[]{dbTable,lambda});

尽可能地优化构造的lambda可以缓存,因此我们不需要每次都构建它,但它的工作原理应该与您可以在运行时构建表达式的工作原理相同。您还需要有
SingleOrDefault
方法的通用版本。下面是一个例子:

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 });
Type tableType=typeof(incommingtableName);//肉用
字符串idPropertyName=“ID”;//id属性名
int myId=42;//搜索价值
//这里我们动态地构建lambda表达式。它将类似于m=>m.ID=42;
ParameterExpression param=表达式.参数(表类型,“m”);
MemberExpression idProperty=Expression.PropertyOrField(参数,idPropertyName);
ConstantExpression constValue=表达式常数(myId);
BinaryExpression body=表达式.Equal(idProperty,constValue);
var lambda=表达式.lambda(body,param);
//然后我们需要得到泛型方法。由于SingleOrDefault是通用方法,我们正在搜索它,
//然后基于tableType参数进行构造
//在我的示例中,我使用了CodeFirst上下文,但这并不重要
SupplyDepot.DAL.SupplyDepotContext上下文=新的SupplyDepotContext();
var dbTable=context.Set(tableType);
//在这里,我们得到SingleOrDefault(表达式)方法,并将其设置为SingleOrDefault(表达式)
var genericSingleOrDefaultMethod=
typeof(Queryable).GetMethods().First(m=>m.Name==“SingleOrDefault”&&m.GetParameters().Length==2);
var specificSingleOrDefault=genericSingleOrDefaultMethod.MakeGenericMethod(tableType);
//最后,我们用构造的lambda来解释它
var result=specificsinglerdefault.Invoke(null,新对象[]{dbTable,lambda});

尽可能地优化构造的lambda可以缓存,因此我们不需要每次都构建它,但它的工作原理应该与您可以在运行时构建表达式的工作原理相同。您还需要有
SingleOrDefault
方法的通用版本。下面是一个例子:

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 });
Type tableType=typeof(incommingtableName);//肉用
字符串idP