我尝试使用基于lambda表达式的实体框架实现通用项目过滤器,告诉我id字段。以下代码编译但当然不起作用,因为EF不理解通用函数:
public static IQueryable<T> Authorize<T>(this IQueryable<T> items, Func<T, Guid> idGetter) where T : class
{
return items.Where(i => idGetter(i) == new Guid("4A6FE5AF-AB63-4BB3-9D32-88766CF242CC"));
}
var result = context.Items.Authorize(i => i.Id);
如何使用EF执行此操作?如何使用表达式树告诉他要比较哪个字段?如何在可由Entity Framework处理的查询中使用通用名称?
答案 0 :(得分:0)
如果您的ID字段始终为Guid
类型(正如您的代码所示),那么您的类可以实现一个名为Id
的成员调用Guid
的接口:
public interface MyInterface
{
Guid Id { get; set; }
}
public class Item : MyInterface
{
public Guid Id { get; set; }
// ...
}
然后您的Authorize方法可能如下所示:
public static IQueryable<T> Authorize<T>(this IQueryable<T> items) where T : MyInterface
{
return items.Where(i => i.Id == new Guid("4A6FE5AF-AB63-4BB3-9D32-88766CF242CC"));
}
您可以按如下方式使用:
var result = items.AsQueryable().Authorize();
答案 1 :(得分:0)
根据您的评论和反思,这是我的方法:
首先,您的(简单)Attribute
来装饰您的&#34; id字段&#34;:
[AttributeUsage(AttributeTargets.Property)]
public class IdFieldAttribute : Attribute
{
public IdFieldAttribute()
{
}
}
然后你的课程看起来像这样:
public class Item
{
[IdFieldAttribute]
public Guid YourIdField{ get; set; }
// ...
}
用于获取所需字段的Reflection
辅助类:
public static class ReflectionHelper
{
public static PropertyInfo GetPropertyInfoByAttribute<T>(T o, Type attributeType) where T : class
{
var type = o.GetType();
var propertyInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.FirstOrDefault(pi => Attribute.IsDefined(pi, attributeType));
return propertyInfo;
}
}
完成此操作后,您的Authorize
方法可能如下所示:
public static IQueryable<T> Authorize<T>(this IQueryable<T> items) where T : class
{
return items.Where(i => (Guid)ReflectionHelper.GetPropertyInfoByAttribute(i, typeof(IdFieldAttribute)).GetValue(i) == new Guid("4A6FE5AF-AB63-4BB3-9D32-88766CF242CC"));
}
你可以按如下方式使用它:
var result = items.AsQueryable().Authorize();
我不知道你正在寻找的东西是不是这样的。也许这种方法可以帮助你。