使用Equals和Array构建动态Linq查询

时间:2014-06-10 12:57:04

标签: c# linq where dynamic-linq

我一直在尝试解决我的应用程序中需要的动态linq查询的语法。

我有一个动态查询,需要将where子句指定为

  • GuidPrimaryKey包含在Guid OR
  • 列表中
  • GuidPrimaryKey等于Guid列表中的项目(使用某种类型的for循环)

我有一个Guid [],其中包含超过5,000个键。我的查询设置为

如果我这样做(作为测试)它是成功的

data = data.where("GuidPrimaryKey.Equals(@0)",array[0]);

以及

data = data.where("GuidPrimaryKey.Equals(@0) OR GuidPrimaryKey.Equals(@1)",array[0], array[1]);

我尝试过:data = data.where("GuidPrimaryKey.Contains(@0)",array);但是会​​出错:“Guid”类型中没有适用的“包含”方法。

我还尝试设置一个循环来遍历数组中的元素,并将where子句设置为一个巨大的字符串,但这也不起作用。

string s = "";
string p = ""
int counter = 0;
foreach(Guid g in Array)
{
s+= "GuidPrimaryKey.Equals(@" counter.ToString() + ") OR";
p += "Array[" counter.ToString() + "],";
counter++;
}

s = s.remove(s.length - 3, 3);
p = p.remove(p.length - 1, 1);

data = data.Where(s,p);

这给了我错误信息:“DynamicClass1”类型中没有属性或字段“1”

有什么想法吗?我需要使用where子句构建查询以检查密钥列表中是否存在主键(GuidPrimaryKey)(Guid [])。

1 个答案:

答案 0 :(得分:1)

我不确定这是否适用于标准的Dynamic Linq库,但我只是尝试了这是my open-source version,它运行良好:

var data = data.Where("GuidPrimaryKey in @0", array);

这也有效:

var data = data.Where("@0.Contains(GuidPrimaryKey)", array);

这是我写的一个完整的单元测试来证实这一点:

[TestMethod]
public void ExpressionTests_ContainsGuid()
{
    //Arrange

    //Generate some users with Id fields of type Guid
    var userList = User.GenerateSampleModels(5, false); 
    var userQry = userList.AsQueryable();

    //Generate a list of values that will fail.
    var failValues = new List<Guid>() { 
        new Guid("{22222222-7651-4045-962A-3D44DEE71398}"), 
        new Guid("{33333333-8F80-4497-9125-C96DEE23037D}"), 
        new Guid("{44444444-E32D-4DE1-8F1C-A144C2B0424D}") 
    };

    //Add a valid Guid so that this list will succeed.
    var successValues = failValues.Concat(new[] { userList[0].Id }).ToArray();


    //Act
    var found1 = userQry.Where("Id in @0", successValues);
    var found2 = userQry.Where("@0.Contains(Id)", successValues);
    var notFound1 = userQry.Where("Id in @0", failValues);
    var notFound2 = userQry.Where("@0.Contains(Id)", failValues);

    //Assert
    Assert.AreEqual(userList[0].Id, found1.Single().Id);
    Assert.AreEqual(userList[0].Id, found2.Single().Id);
    Assert.IsFalse(notFound1.Any());
    Assert.IsFalse(notFound2.Any());
}