Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.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# 在不使用PredicateBuilder的情况下向表达式动态添加谓词_C#_Entity Framework_Linq_Entity Framework 6_Linq To Entities - Fatal编程技术网

C# 在不使用PredicateBuilder的情况下向表达式动态添加谓词

C# 在不使用PredicateBuilder的情况下向表达式动态添加谓词,c#,entity-framework,linq,entity-framework-6,linq-to-entities,C#,Entity Framework,Linq,Entity Framework 6,Linq To Entities,我使用linqToEntities,并希望动态添加或条件 我知道,它可以解决我的任务,但我不能使用它 我的情况如下: IEnumerable<Condition> conditions = new List<Condition>() { new Condition(){IdReference = 1, TableName = "Table1" }, new Condition(){IdReference = 2, TableName = "Table2"

我使用
linqToEntities
,并希望动态添加
条件

我知道,它可以解决我的任务,但我不能使用它

我的情况如下:

IEnumerable<Condition> conditions = new List<Condition>()
{
    new Condition(){IdReference = 1, TableName = "Table1" },
    new Condition(){IdReference = 2, TableName = "Table2" },
    new Condition(){IdReference = 3, TableName = "Table3" }, 
    // and so on
};
if (conditions.Any())
{
    var parameter = Parameter(typeof(History));
    var body = conditions
        .Select(condition => Expression.Constant(condition))
        .Select(condition => Expression.AndAlso(
        Expression.Equal(
            Expression.PropertyOrField(parameter, nameof(History.IdReference)),
            Expression.Convert(
                  Expression.PropertyOrField(condition, nameof(Condition.IdReference))
                , Expression.PropertyOrField(parameter, nameof(History.IdReference)).Type)
        ),
        Expression.Equal(
            Expression.PropertyOrField(parameter, nameof(History.TableName)),
            Expression.Convert(
                  Expression.PropertyOrField(condition, nameof(Condition.TableName))
                , Expression.PropertyOrField(parameter, nameof(History.TableName)).Type)
         )
        ))
        .Aggregate(Expression.OrElse);                      
    var predicate = Lambda<Func<History, bool>>(body, parameter);
    histories = histories.Where(predicate);
}
IEnumerable条件=新列表()
{
新条件(){IdReference=1,TableName=“Table1”},
新条件(){IdReference=2,TableName=“Table2”},
新条件(){IdReference=3,TableName=“Table3”},
//等等
};
我得到的是:

var histories = db.History as IQueryable<History>;
foreach (var cond in conditions)
{
     //What code should be here to be translated into:
     /*
     histories = histories
        .Where(h => h.IdReference == 1 && h.TableName =="Table1" 
            || h.IdReference == 2 && h.TableName == "Table2"
            || h.IdReference == 3 && h.TableName == "Table3");
            // and so on
     */
}    
var histories=db.History作为IQueryable;
foreach(条件中的var cond)
{
//这里应该翻译成什么代码:
/*
历史=历史
。其中(h=>h.IdReference==1&&h.TableName==“Table1”
||h.IdReference==2&&h.TableName==“Table2”
||h.IdReference==3&&h.TableName==“Table3”);
//等等
*/
}    
但是,我事先不知道会有多少个
条件。

如何从
IEnumerable
动态添加
条件

我理解你的意思

var histories = db.History as IQueryable<History>;
foreach (var cond in conditions)
{
     //What code should be here to be translated into:

     histories = histories
        .Where(h => h.IdReference == cond.IdReference && 
      h.TableName ==cond.TableName );

}    
var histories=db.History作为IQueryable;
foreach(条件中的var cond)
{
//这里应该翻译成什么代码:
历史=历史
其中(h=>h.IdReference==cond.IdReference&&
h、 TableName==cond.TableName);
}    

不确定使用谓词生成器有什么问题-它不一定是LINQ Kit包,所谓的谓词生成器通常是一个带有两个扩展方法的单一静态类-like或my-own
PredicateUtils
from和类似

无论如何,一旦您想要它,当然可以使用简单的类静态方法来构建它

添加以下内容以避免在每次调用之前编写
表达式。

using static System.Linq.Expressions.Expression;
然后用这样的方法:

IEnumerable<Condition> conditions = new List<Condition>()
{
    new Condition(){IdReference = 1, TableName = "Table1" },
    new Condition(){IdReference = 2, TableName = "Table2" },
    new Condition(){IdReference = 3, TableName = "Table3" }, 
    // and so on
};
if (conditions.Any())
{
    var parameter = Parameter(typeof(History));
    var body = conditions
        .Select(condition => Expression.Constant(condition))
        .Select(condition => Expression.AndAlso(
        Expression.Equal(
            Expression.PropertyOrField(parameter, nameof(History.IdReference)),
            Expression.Convert(
                  Expression.PropertyOrField(condition, nameof(Condition.IdReference))
                , Expression.PropertyOrField(parameter, nameof(History.IdReference)).Type)
        ),
        Expression.Equal(
            Expression.PropertyOrField(parameter, nameof(History.TableName)),
            Expression.Convert(
                  Expression.PropertyOrField(condition, nameof(Condition.TableName))
                , Expression.PropertyOrField(parameter, nameof(History.TableName)).Type)
         )
        ))
        .Aggregate(Expression.OrElse);                      
    var predicate = Lambda<Func<History, bool>>(body, parameter);
    histories = histories.Where(predicate);
}
if(conditions.Any())
{
var参数=参数(类型(历史));
变量体=条件
.Select(条件=>Expression.Constant(条件))
.Select(条件=>Expression.AndAlso(
表达式。相等(
Expression.PropertyOrField(参数,名称(History.IdReference)),
表达式。转换(
Expression.PropertyOrField(条件,名称(条件.IdReference))
,Expression.PropertyOrField(参数,名称(History.IdReference)).Type)
),
表达式。相等(
Expression.PropertyOrField(参数,nameof(History.TableName)),
表达式。转换(
Expression.PropertyOrField(条件,名称(条件.表名))
,Expression.PropertyOrField(参数,名称(History.TableName)).Type)
)
))
.聚合(表示为OrElse);
var谓词=Lambda(主体,参数);
历史=历史。其中(谓词);
}

如果没有太多的组合,只需使用一些条件:
If(thisIsTheCase){histories=histories.Where(//put-your-conditions}否则If(另一种情况){histories=histories.Where(//put-your-conditions}
在覆盖所有情况之前,如果其他情况,请添加更多。您也可以通过创建动态表达式来完成,但这并不容易,因为您需要组合表达式。为什么不能使用
PredicateBuilder
?@CodingYoshi,因为我的代码不会通过代码审阅。他在运行时之前不知道条件。这将导致正如我所理解的,他不知道历史列表中有多少个条件,但他在条件列表中有固定的条件,所以在条件列表中循环并比较!!正如我所想:)链接
,其中
s是
的等价物,而不是