具有多个/未知条件的动态linq查询

| 我正在寻找一种实现“构建”条件的系统,然后将结果数据从数据库中返回。当前,有一个存储过程可以即时生成SQL并执行它。这是我要删除的特定问题。 我的问题来自这样一个事实,我可以在自己的条件内包含多个字段,并且对于每个这些字段,可能会有1个或多个值,并且使用不同的潜在运算符。 例如,
from t in Contacts 
where t.Email == \"email@domain.com\" || t.Email.Contains (\"mydomain\")
where t.Field1 == \"valuewewant\"
where t.Field2 != \"valuewedontwant\"
select t
字段,条件和运算符存储在数据库中(和
List<FieldCriteria>
),将是类似的东西(基于上述内容);
Email, Equals, \"email@domain.com\"
Email, Contains, \"mydomain\" Field1,
Equals, \"valuewewant\" Field2,
DoesNotEqual, \"valuewedontwant\"
要么
new FieldCriteria
{
FieldName = \"Email\",
Operator = 1, 
Value = \"email@mydomain.com\"
}
因此,使用我所拥有的信息,我希望能够构建具有任意数量条件的查询。我已经看到了以前与Dynamic Linq和PredicateBuilder的链接,但是无法将其可视化为自己的问题的解决方案。 任何建议,将不胜感激。 更新资料 根据有关Dynamic Linq的建议,我提出了一个非常基本的解决方案,使用具有2个字段和多个条件的单个运算符。目前,LinqPad中的代码有些粗糙,但是结果正是我想要的;
enum Operator
{
    Equals = 1,
}

class Condition
{
    public string Field { get; set; }
    public Operator Operator { get; set;}
    public string Value { get; set;}
}

void Main()
{
    var conditions = new List<Condition>();

    conditions.Add(new Condition {
        Field = \"Email\",
        Operator = Operator.Equals,
        Value = \"email1@domain.com\"
    });

    conditions.Add(new Condition {
        Field = \"Email\",
        Operator = Operator.Equals,
        Value = \"email2@domain.com\"
    });

    conditions.Add(new Condition {
        Field = \"Field1\",
        Operator = Operator.Equals,
        Value = \"Chris\"
    });

    var statusConditions = \"Status = 1\";

    var emailConditions = from c in conditions where c.Field == \"Email\" select c;
    var field1Conditions = from c in conditions where c.Field == \"Field1\" select c;


    var emailConditionsFormatted = from c in emailConditions select string.Format(\"Email=\\\"{0}\\\"\", c.Value);
    var field1ConditionsFormatted = from c in field1Conditions select string.Format(\"Field1=\\\"{0}\\\"\", c.Value);

    string[] conditionsArray = emailConditionsFormatted.ToArray();
    var emailConditionsJoined = string.Join(\"||\", conditionsArray);
    Console.WriteLine(String.Format(\"Formatted Condition For Email: {0}\",emailConditionsJoined));

    conditionsArray = field1ConditionsFormatted.ToArray();
    var field1ConditionsJoined = string.Join(\"||\", conditionsArray);
    Console.WriteLine(String.Format(\"Formatted Condition For Field1: {0}\",field1ConditionsJoined));



    IQueryable results = ContactView.Where(statusConditions);

    if (emailConditions != null)
    {
        results = results.Where(emailConditionsJoined);
    }

    if (field1Conditions != null)
    {
        results = results.Where(field1ConditionsJoined);
    }

    results = results.Select(\"id\");

    foreach (int id in results)
    {
        Console.WriteLine(id.ToString());
    }
}
用SQL生成的;
-- Region Parameters
DECLARE @p0 VarChar(1000) = \'Chris\'
DECLARE @p1 VarChar(1000) = \'email1@domain.com\'
DECLARE @p2 VarChar(1000) = \'email2@domain.com\'
DECLARE @p3 Int = 1
-- EndRegion
SELECT [t0].[id]
FROM [Contacts].[ContactView] AS [t0]
WHERE ([t0].[field1] = @p0) AND (([t0].[email] = @p1) OR ([t0].[email] = @p2)) AND ([t0].[status] = @p3)
和控制台输出:
Formatted Condition For Email: Email=\"email1@domain.com\"||Email=\"email2@domain.com\"
Formatted Condition For Field1: Field1=\"Chris\"
只需清理一下并添加其他运算符,它看起来就不错。 到目前为止,如果有人对此有任何评论,我们将不胜感激     
已邀请:
        我认为Dynamic LINQ将是一种选择。 DLINQ允许您将LINQ查询的一部分指定为\“ string \”,然后DLINQ将该字符串编译为表达式树,以便传递给基础LINQ提供程序。您的需求也相同,即您需要在运行时创建表达式树。 我建议您将属性ѭ7中的ѭ7设为ѭ9,代表所有必需的运算(等于,小于等)。然后,您将需要编写一个函数,该函数带有一个
FieldCriteria
的列表并返回一个\“ expression \”字符串,然后可以将其馈送到DLINQ中以获取表达式树。     
        LINQ的诀窍是从数据中构建一个“ 11”。例如,为了说明所示的示例:
var param = Expression.Parameter(typeof(MyObject), \"t\");

var body = Expression.Or(
            Expression.Equal(Expression.PropertyOrField(param, \"Email\"), Expression.Constant(\"email@domain.com\")),
            Expression.Call(Expression.PropertyOrField(param, \"Email\"), \"Contains\", null, Expression.Constant(\"mydomain\"))
        );

body = Expression.AndAlso(body, Expression.Equal(Expression.PropertyOrField(param, \"Field1\"), Expression.Constant(\"valuewewant\")));
body = Expression.AndAlso(body, Expression.NotEqual(Expression.PropertyOrField(param, \"Field2\"), Expression.Constant(\"valuewedontwant\")));

var lambda = Expression.Lambda<Func<MyObject, bool>>(body, param);

var data = source.Where(lambda);
尤其要注意如何使用ѭ13构成各种操作(与多个
Where
相同,但更简单)。     
        这可以通过Linq轻松完成,您可以在其中附加其他运算符到查询对象。这是一个例子。
query = db.Contacts.Where( ... );
 query = query.Where( ... );
 query = query.Where( ... );
这是一个更简单,更短的解决方案。     

要回复问题请先登录注册