gpt4 book ai didi

c# - 如何使用反射简化 Linq 扩展方法调用?

转载 作者:太空狗 更新时间:2023-10-29 21:40:38 25 4
gpt4 key购买 nike

背景:

我有一个 Web 服务,它返回表(作为参数提供的表名)中 ID 大于特定 ID(也作为参数提供)的行。我们假设 ID 是连续的。

我正在使用 Linq to SQL 进行数据库交互,所以我想将新行返回为:

List<WhateverObject>

因为我们只知道运行时的表名,所以我无法以正常方式使用 Linq,这让事情变得更加复杂。

问题:

代码在下面(并且有效)。我怎样才能简化它?这似乎过于复杂。

private object GetUpdateList(string tableName, int Id, DataClassesDataContext db)
{
PropertyInfo pi = db.GetType().GetProperty(tableName);

var table = pi.GetValue(db, null);

// Get type of object within the table.
Type genericType = table.GetType().GetGenericArguments()[0];

// The Where method lives on the Enumerable type in System.Linq
var whereMethods = typeof(System.Linq.Enumerable)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(mi => mi.Name == "Where");

// There are actually 2 where methods - we want the one with 2 parameters
MethodInfo whereMethod = null;
foreach (var methodInfo in whereMethods)
{
var paramType = methodInfo.GetParameters()[1].ParameterType;
if (paramType.GetGenericArguments().Count() == 2)
{
// we are looking for Func<TSource, bool>, the other has 3
whereMethod = methodInfo;
break;
}
}

Func<object, bool> IdEquals = BuildEqFuncFor("Id", Id);

whereMethod = whereMethod.MakeGenericMethod(genericType);
var result = whereMethod.Invoke(table, new object[] { table, IdEquals });

MethodInfo toListMethod = typeof(System.Linq.Enumerable).GetMethod("ToList").MakeGenericMethod(genericType);
return toListMethod.Invoke(result, new object[] { result });
}

// Build lambda expression for use in Linq
private static Func<object, bool> BuildEqFuncFor(string prop, object val)
{
// We know we are comparing integers here so cast them.
// There is probably a more general solution.
return t => (int)t.GetType().InvokeMember(prop, BindingFlags.GetProperty, null, t, null) > (int)val;
}

为了提出这个解决方案,我不得不引用以下问题:

最佳答案

尝试这样的事情:

private IList GetUpdateList(string tableName, int id, DataClassesDataContext db)
{
System.Reflection.PropertyInfo pi = db.GetType().GetProperty(tableName);

var table = pi.GetValue(db, null);

// Get type of object within the table.
Type genericType = table.GetType().GetGenericArguments()[0];

var param = Expression.Parameter(genericType, "x");
var predicateExpr = Expression.Lambda(
Expression.GreaterThan(
Expression.Property(param, "Id"),
Expression.Constant(id)),
param);

return this
.GetType()
.GetMethod("GetUpdateListGeneric")
.MakeGenericMethod(genericType)
.Invoke(this, new[] { table, predicateExpr }) as IList;
}

private IList<T> GetUpdateListGeneric<T>(
Table<T> table,
Expression<Func<T, bool>> predicate) where T : class
{
return table.Where(predicate).ToList();
}

关于c# - 如何使用反射简化 Linq 扩展方法调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11661112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com