c# - 在 linq to EF 中,我可以创建一个动态查询来搜索用户指定的字段吗

标签 c# entity-framework linq

我们将一些用户定义的数据存储在一个表中,其中包含名为“Date01”、“Date02”、“Text01”、“Text02”、“Number01”、“Number02”等的列。用户配置使用哪些列以及使用哪些列存储在这些列中的数据意味着。

我们现在需要允许用户搜索此数据。

我可以这样写:

if (property.Name.StartsWith("Date") && search.Value is DateTime)
{
    switch (property.Name)
    {
        case "Date01":
            results = table.Where(clf => clf.Date01.HasValue && clf.Date01.Value.Date == ((DateTime)search.Value).Date);
            break;
        case "Date02":
            results = table.Where(clf => clf.Date02.HasValue && clf.Date02.Value.Date == ((DateTime)search.Value).Date);
            break;
        case "Date03":
            ....
    }
}
else if (property.Name.StartsWith("Text") && search.Value is string)
{
    switch (property.Name)
    {
        case "Text01":
            results = table.Where(clf => clf.Text01 == (string)search.Value);
            break;
        case "Text02":
            results = table.Where(clf => clf.Text02 == (string)search.Value);
            break;
        case "Text03":
            ....
    }
}

但我觉得这可能效率低下、难以维护且难以扩展。

“搜索”是一个字典,它以用户对列的调用为关键字,并保存要搜索的值。

我想写的是这样的:

results = table.Where(t => GetProperty(t, search.Term) == search.Value);

但我知道这行不通。

我准备保留 if/switch 语句,这样我就可以进行适当的相等性测试,但我真的很想避免为每种类型使用 20 项大的 switch/if 语句。

最佳答案

您可以使用类似这样的东西来构建表达式:

public Expression<Func<T, bool>> GetMatchExpression<T>(
    string propertyName, 
    object propertyValue)
{
    var parameterExp = Expression.Parameter(typeof(T), "t");
    var propertyExp = Expression.PropertyOrField(parameterExp, propertyName);
    var method = propertyExp.Type.GetMethod("Equals", new[] { propertyExp.Type });
    var someValue = Expression.Constant(propertyValue);
    var methodExpression = Expression.Call(propertyExp, method, someValue);

    return Expression.Lambda<Func<T, bool>>(methodExpression, parameterExp);
}

你会像这样使用它:

results = table.Where(GetMatchExpression<Table>(search.Term, search.Value));

关于c# - 在 linq to EF 中,我可以创建一个动态查询来搜索用户指定的字段吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57757496/

相关文章:

c# - 使用 LINQ 构建递归层次结构

c# openfiledialog 选择多个文件,其顺序与用户选择的顺序相同

c# - CS1003 语法错误,预期为 'when'

c# - AutoMapper 的 Ignore() 在使用 ForSourceMember 时不起作用?

c# - MiniProfiler ASP.NET Core - 基于用户角色的 ShouldProfile

entity-framework - EF6 代码首先复数表无效的对象名称

c# - 使用虚假数据进行 wcf 服务测试

c# - 如何在 Entity Framework Core 中创建基类和派生类组合的复合键

c# - 处理并计算数据库中保存的公式

c# - 在 LINQ 中并行加载图像