代码之家  ›  专栏  ›  技术社区  ›  ladenedge

EF/LINQ:针对子类型属性的Where()

  •  0
  • ladenedge  · 技术社区  · 15 年前

    我有一套POCO,它们都实现了以下简单接口:

     interface IIdObject
     {
         int Id { get; set; }
     }
    

    这些POCO的一个子集实现了这个附加接口:

     interface IDeletableObject : IIdObject
     {
         bool IsDeleted { get; set; }
     }
    

    我的存储库层次结构如下所示:

    i假定<T>&书信电报;:基本存款<T>&书信电报;:验证存储库<T>(其中T是IID对象)

    我想添加一个 IDeletableObject 有一个 Where(p => p.IsDeleted == false)

    我的第一次尝试是这样的:

    public override IQueryable<T> Query()
    {
        return base.Query().Where(t => ((IDeletableObject)t).IsDeleted == false);
    }
    

    “LINQ to Entities仅支持转换实体数据模型基元类型。”

    interface IQueryFilter<out T>  // error
    {
        Expression<Func<T, bool>> GetFilter();
    }
    

    如果有帮助的话,我很乐意更详细地介绍我更复杂的解决方案,但我想我现在就到此为止,希望有人能给我一个想法。

    非常感谢!

    1 回复  |  直到 15 年前
        1
  •  1
  •   LukLed    15 年前

    这太大了,无法评论,所以。。。

    可以动态创建表达式。我创建了助手方法:

    public static class ExpressionHelper
    {
        public static MemberExpression PropertyExpression(this Expression expr,string propertyName)
        {           
            var properties = propertyName.Split('.');
    
            MemberExpression expression = null;
    
            foreach (var property in properties)
            {
                if (expression == null)
                    expression = Expression.Property(expr, property);
                else
                    expression = Expression.Property(expression, property);
            }
    
            return expression;
        }
    
        public static BinaryExpression EqualExpression<T>(this Expression expr, string propertyName, T value)
        {
            return Expression.Equal(expr.PropertyExpression(propertyName), Expression.Constant(value, typeof(T)));
        }
    }
    

    //Checking if T implements IDeletableObject
    if (typeof(IDeletableObject).IsAssignableFrom(typeof(T)))
    {
        //a
        var parameter = Expression.Parameter(typeof(T), "a");
        //a.IsDeleted == false
        var where = parameter.EqualExpression("IsDeleted", false);
        //a => a.IsDeleted == false
        var condition = Expression.Lambda<Func<T, bool>>(where, parameter);
        list = list.Where(condition);
    }
    

    编辑

    你也可以使用 Dynamic Linq Library