gpt4 book ai didi

c# - Linq 表达式作为参数

转载 作者:行者123 更新时间:2023-11-30 22:06:06 24 4
gpt4 key购买 nike

我想调用IQueryable<T>我的存储库中的方法,但我想在我的 ORM 中急切地加载子对象。为了将持久性逻辑保留在持久性层中,我想传递一个表达式列表,表示我想要急切加载的属性。

我的 IRepository<TClass>方法如下所示:

IQueryable<TClass> AsQueryable();

我想让它看起来像:

IQueryable<TClass> AsQueryable(params --something here--[] includeProperties);

...这样我就可以这样调用它:

var q = myFooRepository.AsQueryable(x => x.Property1, x => x.Property2, ...);

并在后端反汇编委托(delegate)以预先加载指定的属性。

我应该为此使用什么?

最佳答案

你的 AsQueryable<TClass>应该将属性表达式作为参数,并且需要具有以下签名:

public static IQueryable<TClass> AsQueryable<TClass>(this TClass obj, params Expression<Func<TClass, object>>[] propertyExpressions)

请注意,我们使用的是 Func<TClass, object>这是一个接受 TClass 作为输入并返回对象的函数。这使我们可以按如下方式进行调用:

IQueryable<TClass> tClassQueryable = tClassObj.AsQueryable(x => x.Property1, x => x.Property2);

另请注意,我没有选择 object作为 Func<TClass, object> 的 TResult偶然。由于函数委托(delegate)的 TResult 泛型参数是协变的,这允许我们传递具有不同属性类型的表达式。所以上例中的 Property1 和 Property2 不需要是同一类型。

就是这样,我想关于你的问题,但这里有一点额外的:

如果您偶然需要评估传递的表达式以便将它们与您的 ORM 一起使用(例如,您只需要属性名称但您希望将它们作为表达式传递以避免对名称进行硬编码并保留编译时检查),你需要这样的东西:

  public static IQueryable<TClass> AsQueryable<TClass>(this TClass obj, params Expression<Func<TClass, object>>[] propertyExpressions)
{
foreach (var propertyExpression in propertyExpressions)
{
MemberExpression memberExpression = propertyExpression.Body as MemberExpression;

if (memberExpression == null)
{
// this is needed for value types properties.
UnaryExpression unaryExpression = (UnaryExpression)propertyExpression.Body;
memberExpression = unaryExpression.Operand as MemberExpression;
}

if (memberExpression == null)
throw new ArgumentException(string.Format("Expression '{0}' is not a member expression.", propertyExpression.ToString()));

PropertyInfo propertyInfo = memberExpression.Member as PropertyInfo;
if (propertyInfo == null)
throw new ArgumentException("MemberExpression.Member is not a PropertyInfo.");


// at this point we have PropertyInfo which you can use with your OR Mapper to further implement logic which will eager load the property
// e.g. property name can be retrieved with:
string propertyName = propertyInfo.Name;

// do your ORM stuff here
}
}

上面的代码确保传递的表达式是属性表达式,并从中提取 PropertyInfo。

关于c# - Linq 表达式作为参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23849611/

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