c# – 具有多个/未知标准的动态linq查询

前端之家收集整理的这篇文章主要介绍了c# – 具有多个/未知标准的动态linq查询前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我希望实现一个系统,用于“构建”条件,然后从数据库返回结果数据.目前,有一个存储过程可以动态生成sql并执行它.这是我想要删除的特殊问题.

我的问题来自这样一个事实:我可以在我的标准中包含多个字段,并且对于每个字段,可能有一个或多个值,具有不同的潜在运算符.

例如,

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,"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",Value = "email2@domain.com"
    });

    conditions.Add(new Condition {
        Field = "Field1",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查询的一部分指定为“字符串”,然后DLINQ将该字符串编译为表达式树,以便传递给基础LINQ提供程序.您的需求也是相同的,即您需要在运行时创建表达式树.

我建议你将FieldCriteria中的属性Operator作为Enum来表示所有必需的操作(等于,少于等).然后你需要编写一个函数,它接受一个FieldCriteria列表并返回一个“表达式”字符串,然后可以将其输入DLINQ以获取表达式树.

猜你在找的C#相关文章