c# - 构建表达式以过滤数据 EF Core

标签 c# entity-framework ef-core-2.2 linq-expressions

我需要重用可用的表达式:

Expression<Func<Picture, int>> selector = o => o.EntityId;

并为 Where 构建表达式:

Expression<Func<Picture, bool>> filter = w => w.EntityId > 5;

如何构建这样的表达式?

下一个操作不会在客户端执行,对吗?

var collection = _dbContext.Pictures.Where(filter).ToList();

最佳答案

我终于想出了如何动态构建表达式:

Expression<Func<Picture, int>> selector = o => o.EntityId;

var parameter = Expression.Parameter(typeof(Picture));

// get property name
if (!(selector.Body is MemberExpression memberExpression))
{
    memberExpression = ((UnaryExpression)selector.Body).Operand as MemberExpression;
}
var propertyName = memberExpression.ToString().Substring(2);

var expressionParameter = Expression.Property(parameter, propertyName);
var expressionBody = Expression.GreaterThan(expressionParameter, Expression.Constant(5, typeof(int)));

var filter = Expression.Lambda<Func<Picture, bool>>(expressionBody, parameter);
var collection = _dbContext.Pictures.Where(filter).ToList();

通用示例:

var filter = CreateFilter<Picture, int>(o => o.EntityId, 5);
var collection = _dbContext.Pictures.Where(filter).ToList();

private Expression<Func<TData, bool>> CreateFilter<TData, TKey>(Expression<Func<TData, TKey>> selector, TKey valueToCompare)
{
    var parameter = Expression.Parameter(typeof(TData));
    var expressionParameter = Expression.Property(parameter, GetParameterName(selector));

    var body = Expression.GreaterThan(expressionParameter, Expression.Constant(valueToCompare, typeof(TKey)));
    return Expression.Lambda<Func<TData, bool>>(body, parameter);
}

private string GetParameterName<TData, TKey>(Expression<Func<TData, TKey>> expression)
{
    if (!(expression.Body is MemberExpression memberExpression))
    {
        memberExpression = ((UnaryExpression)expression.Body).Operand as MemberExpression;
    }

    return memberExpression.ToString().Substring(2);
}

感谢 David 关于 Prohibit client-side evaluation 的回复, 我能够验证过滤没有在客户端上执行

关于c# - 构建表达式以过滤数据 EF Core,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61412241/

相关文章:

c# - 在 RadDatePicker 中将当前 PC 日期和时间设置为默认值

c# - 在 Entity Framework 中获取属性的映射列名称

asp.net-mvc - ASP.NET MVC - View 模型、域模型和数据模型

c# - 如何在拥有的实体中定义关系属性的名称

c# - 如何在我的业务逻辑层中管理统一性?

c# - 在 LINQ 查询中使用 Max - 列表中的空值

c# - 如何使用 C# 在 Selenium 中处理 firefox 的另存为对话框?

sql - 如何让 Entity Framework 使用存档标志?

c# - "The type mapping for ' Instant ' has not implemented code literal generation"分割实体时

c# - 后退按钮硬件不刷新页面 xamarin forms c#