根据动态字段过滤IQueryable

时间:2016-11-01 09:54:16

标签: entity-framework lambda

我尝试使用基于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处理的查询中使用通用名称?

2 个答案:

答案 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();

我不知道你正在寻找的东西是不是这样的。也许这种方法可以帮助你。