Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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# 根据用户选择生成LinqToEntities Where语句_C#_Entity Framework_Optimization - Fatal编程技术网

C# 根据用户选择生成LinqToEntities Where语句

C# 根据用户选择生成LinqToEntities Where语句,c#,entity-framework,optimization,C#,Entity Framework,Optimization,我有一个用户界面,用户可以在其中为该列选择网格列(如年龄)和运算符(小于、等于或大于) 然后根据选择过滤网格数据 我有一个从来自客户端的JSON反序列化的类 /// <summary> /// Filter for reducing grid results /// </summary> public class Filter { /// <summary> /// Name of the column /// </summary

我有一个用户界面,用户可以在其中为该列选择网格列(如年龄)和运算符(小于、等于或大于)

然后根据选择过滤网格数据

我有一个从来自客户端的JSON反序列化的类

/// <summary>
/// Filter for reducing grid results
/// </summary>
public class Filter
{
    /// <summary>
    /// Name of the column
    /// </summary>
    public string name;

    public string value;

    public int @operator { private get; set; }

    public Operator Operator()
    {
        return (Operator) @operator;
    }
}

public enum Operator
{
    None = -1,
    LesserThan = 0,
    Equals = 1,
    GreaterThan = 2
}
//
///用于减少网格结果的过滤器
/// 
公共类过滤器
{
/// 
///列名
/// 
公共字符串名称;
公共字符串值;
公共int@operator{private get;set;}
公共运营商()
{
返回(操作员)@操作员;
}
}
公共枚举运算符
{
无=-1,
小于等于0,
等于等于1,
大于等于2
}
由于动态添加用于筛选的新列的性质,我希望创建用于访问数据的通用解决方案

我希望避免使用大量if/switch语句,如

switch(columnName)
{
    case "age":
    {
        if(operator == Operator.LesserThan)
        {
             query = entities.Where(o => o.Age < age);
        }
        else if (operator == Operator.GreaterThan)
        {
             query = entities.Where(o => o.Age > age);
        }
        etc.

        break;
    }
    etc.
}
开关(列名称)
{
案例“年龄”:
{
if(运算符==运算符.小于)
{
查询=实体。其中(o=>o.Ageo.Age>Age);
}
等
打破
}
等
}
有没有办法为这个问题创建更通用的解决方案

更新 似乎有许多方法可以实现比10亿个if语句更清洁的解决方案。现在,我只需要比较不同的解决方案。

您可以使用基于所需内容的动态构建linq查询。这将帮助您轻松构建linq表达式。至于会随着时间不断增长的丑陋开关,我建议,如果“name”总是与linq表达式中的某个属性相关(例如“age”-->.age),那么您应该能够通过一些反射代码获得它-因此您可以检查“name”是否与同名属性相关,如果是,则为其构建一个过滤器

HTH

您可以使用根据所需内容动态构建linq查询。这将帮助您轻松构建linq表达式。至于会随着时间不断增长的丑陋开关,我建议,如果“name”总是与linq表达式中的某个属性相关(例如“age”-->.age),那么您应该能够通过一些反射代码获得它-因此您可以检查“name”是否与同名属性相关,如果是,则为其构建一个过滤器

HTH

您可以使用动态创建查询

编辑:

动态LINQ查询的示例如下所示,假设网格中的列名与实体中的字段名相同:

string queryString;
queryString = columnName;
if(operator == Operator.LesserThan)
{
  queryString += " < ";
}
else if (operator == Operator.GreaterThan)
{
  queryString += " > ";
}
etc.
queryString += age.ToString();  // Or use bind variables, haven't tried that myself in dynamic LINQ

query = entites.Where(queryString);
字符串查询字符串;
queryString=columnName;
if(运算符==运算符.小于)
{
查询字符串+=“<”;
}
else if(operator==operator.GreaterThan)
{
查询字符串+=“>”;
}
等
queryString+=age.ToString();//或者使用绑定变量,我自己还没有在动态LINQ中尝试过
query=entites.Where(queryString);
您可以使用动态创建查询

编辑:

动态LINQ查询的示例如下所示,假设网格中的列名与实体中的字段名相同:

string queryString;
queryString = columnName;
if(operator == Operator.LesserThan)
{
  queryString += " < ";
}
else if (operator == Operator.GreaterThan)
{
  queryString += " > ";
}
etc.
queryString += age.ToString();  // Or use bind variables, haven't tried that myself in dynamic LINQ

query = entites.Where(queryString);
字符串查询字符串;
queryString=columnName;
if(运算符==运算符.小于)
{
查询字符串+=“<”;
}
else if(operator==operator.GreaterThan)
{
查询字符串+=“>”;
}
等
queryString+=age.ToString();//或者使用绑定变量,我自己还没有在动态LINQ中尝试过
query=entites.Where(queryString);

您可以将输入组成的System.Linq.Expressions.Expression对象传递给Where方法。下面是一个如何组合谓词表达式以用于EF或Linq2Sql的示例:

您可以将根据输入合成的System.Linq.Expressions.Expression对象传递给Where方法。下面是一个如何组合谓词表达式以用于EF或Linq2Sql的示例:

您可以使用ESQL而不仅仅是LINQ:

Context.Entities
    .Where("it.Age > @Age", new[] { new ObjectParameter("Age", age } );
您可以根据您拥有的过滤器轻松地为您的条件生成字符串表示形式


以下是您需要它时的提示。

您可以使用ESQL而不仅仅是LINQ:

Context.Entities
    .Where("it.Age > @Age", new[] { new ObjectParameter("Age", age } );
您可以根据您拥有的过滤器轻松地为您的条件生成字符串表示形式


这是您需要的反射代码。

您可以使用反射代码,例如:

String columName; //your dynamic columnName

if(operator == Operator.LesserThan)
        {
             query = entities.Where(o => o.GetType().GetProperty(columName).GetValue(o, null) <columName);
        }
        else if (operator == Operator.GreaterThan)
        {
            etc.
        }
字符串列名//您的动态列名称
if(运算符==运算符.小于)
{

query=entities.Where(o=>o.GetType().GetProperty(columName).GetValue(o,null)您可以使用反射代码,例如:

String columName; //your dynamic columnName

if(operator == Operator.LesserThan)
        {
             query = entities.Where(o => o.GetType().GetProperty(columName).GetValue(o, null) <columName);
        }
        else if (operator == Operator.GreaterThan)
        {
            etc.
        }
String columnName;//您的动态columnName
if(运算符==运算符.小于)
{

query=entities.Where(o=>o.GetType().GetProperty(ColumnName).GetValue(o,null)很好!我想这正是我需要的。现在我只需要检查关于动态LINQ的其他答案,并决定哪一个更合适。然后我将选择获胜的答案。非常好!我认为这正是我需要的。现在我只需检查关于动态LINQ的其他答案,并决定哪一个更合适。我将然后,我会选择获胜的答案。我认为它很好,很简单。我认为它很好,很简单。为了让你的答案更具描述性和完整性,你能分享一个适用于OP用例的样本吗?你能分享一个适用于OP用例的样本,以便让你的答案更具描述性和完整性吗特朗普?