我想将谓词构建逻辑移动到基类中,并且得到错误“LINQ表达式节点类型'调用' LINQ to Entities不支持“。我希望能够在谓词中连接或有条件地链接表达式。
我希望能够传入谓词的一部分,该谓词对于调用者来说是唯一的属性名称( GetFilterPredicate 将成为一个通用例程,它将对将要使用的类型进行操作有不同的属性名称持有相关的值)。
protected Expression<Func<MyEntity, bool>> GetFilterPredicate(
PagingParameters pagingParameters,
Func<MyEntity, DateTime?> terminationDate,
Func<MyEntity, string> entityID,
Func<MyEntity, string> name
)
{
Expression<Func<MyEntity, bool>> validFilter = x => true;
if (pagingParameters.Active == true)
{
validFilter = x => terminationDate(x) > DateTime.Now;
}
///more conditions added here
return validFilter;
}
protected List<MyEntity> Query(IQueryable<MyEntity> source)
{
var filters = GetFilterPredicate(
new PagingParameters() { Active = true }
, i => i.TerminationDate
, i => i.EntityID
, i => i.Name
);
return source.Where(filters).AsNoTracking().ToList<MyEntity>();
}
答案 0 :(得分:2)
您无法使用委托terminationDate
构建新表达式,您需要将terminationDate
更改为表达式并使用它来手动构建新表达式。
protected static Expression<Func<MyEntity, bool>> GetFilterPredicate(
PagingParameters pagingParameters,
Expression<Func<MyEntity, DateTime?>> terminationDate,
Expression<Func<MyEntity, string>> entityID,
Expression<Func<MyEntity, string>> name
)
{
Expression<Func<MyEntity, bool>> validFilter = x => true;
// We need to replace the parameter for all expressions with
// a common single parameter. I used the parameter for the default
// filter but a new Parameter expression would have worked as well.
// If you don't do this you will get an error (unbound parameter or something like that ) because the parameter
// used in the expressions (terminationDate, entityID) will be
// different then the parameter used for the new validFilter expression
var parameterReplacer = new ReplaceVisitor
{
NewParameter = validFilter.Parameters.First()
};
if (pagingParameters.Active == true)
{
validFilter = Expression.Lambda<Func<MyEntity, bool>>(
Expression.GreaterThan
(
parameterReplacer.Visit(terminationDate.Body),
Expression.Convert(Expression.Property(null, typeof(DateTime), "Now"), typeof(DateTime?))
),
parameterReplacer.NewParameter
);
}
// existing filter && x.EntityId != "A"
validFilter = Expression.Lambda<Func<MyEntity, bool>>(
Expression.And(
validFilter.Body,
Expression.NotEqual
(
parameterReplacer.Visit(entityID.Body),
Expression.Constant("A")
)
),
parameterReplacer.NewParameter
);
return validFilter;
}
/// <summary>
/// Simple Parameter Replacer, will replace the any parameter with the new
/// parameter. You will need to refine this if your expressions have nested
/// lambda, in that you will need to only replace the top most lambda
/// parameter, but for simple expressions it will work fine.
/// </summary>
class ReplaceVisitor : ExpressionVisitor
{
public ParameterExpression NewParameter { get; set; }
protected override Expression VisitParameter(ParameterExpression node)
{
return this.NewParameter;
}
}
答案 1 :(得分:1)
您可以手动执行此操作,如Titian答案所述,但更简单的方法是使用LinqKit。首先安装LinqKit nuget包并添加Invoke
,然后:
Expand
您可以在上面提供的链接上阅读有关 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Hero hero = heroList.get(i);
Intent intent=new Intent(getApplicationContext(),ArticleActivity.class);
//hero want to use any method from your hero object, example : getImageURL();
intent.putExtra("description",hero.getImage());
startActivity(intent);
}
});
和{
"status": "error",
"code": "apiKeyInvalid",
"message": "Your API key is invalid or incorrect. Check your key, or go to https://newsapi.org to create a free API key."
}
的内容。