Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF/LINQ:Where()针对子类型的属性_C#_Linq_Entity Framework_Linq To Entities_Covariance - Fatal编程技术网

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

C# EF/LINQ:Where()针对子类型的属性,c#,linq,entity-framework,linq-to-entities,covariance,C#,Linq,Entity Framework,Linq To Entities,Covariance,我有一套POCO,它们都实现了以下简单接口: interface IIdObject { int Id { get; set; } } interface IDeletableObject : IIdObject { bool IsDeleted { get; set; } } 这些POCO的一个子集实现此附加接口: interface IIdObject { int Id { get; set; } } interface IDeleta

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

 interface IIdObject
 {
     int Id { get; set; }
 }
 interface IDeletableObject : IIdObject
 {
     bool IsDeleted { get; set; }
 }
这些POCO的一个子集实现此附加接口:

 interface IIdObject
 {
     int Id { get; set; }
 }
 interface IDeletableObject : IIdObject
 {
     bool IsDeleted { get; set; }
 }
我的存储库层次结构如下所示:

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

i假设这太大了,无法评论,所以

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

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)));
    }
}
公共静态类ExpressionHelper
{
公共静态MemberExpression PropertyExpression(此表达式expr,字符串propertyName)
{           
var properties=propertyName.Split('.');
MemberExpression=null;
foreach(属性中的var属性)
{
if(表达式==null)
expression=expression.Property(expr,Property);
其他的
expression=expression.Property(表达式,属性);
}
返回表达式;
}
公共静态二进制表达式EqualExpression(此表达式expr,字符串propertyName,T值)
{
返回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);
}
//检查T是否实现了IDeletableObject
if(typeof(IDeletableObject).IsAssignableFrom(typeof(T)))
{
//a
var参数=表达式参数(类型为(T),“a”);
//a、 IsDeleted==false
var,其中=参数.EqualExpression(“IsDeleted”,false);
//a=>a.IsDeleted==false
var条件=表达式.Lambda(其中,参数);
列表=列表。其中(条件);
}
编辑


您也可以使用。它也使用表达式,但并不强迫您考虑它是如何工作的,只需将简单的条件写成字符串即可。我不知道它是如何处理布尔值的。

对此,必须使用非接口类型。EF不知道如何将接口实现转换为SQL。您不能将
where t:IDeletableObject
应用于类型参数吗?从
Repository
继承并使用附加的类型约束创建
DeletableRepository
。@Craig:如果我使用类,我很不幸会遇到多个继承问题:-(@LukLed:现在我的IoC容器中有一条创建存储库的规则。我相信创建新的存储库类型(或重新参数化它们)将需要额外的规范,这是我希望避免的。非常有趣(我非常感谢您的帮助,呵呵)。我会尽快试用!@ladenedge:它应该可以正常工作,但可能需要一些调整。我无法完全测试它。嗯,我在这里对您的代码进行了一些测试,但是动态Linq太简单了,呵呵。生成的代码看起来像:
set.Where(“IsDeleted=@0”,false)
-非常简单!非常感谢您的时间和帮助!@ladenedge:先玩一会儿,然后使用动态linq可能是最好的解决方案:)