简体   繁体   English

使用等于和数组构建动态Linq查询

[英]Building a Dynamic Linq Query using Equals and an Array

I have been trying to solve the syntax for a dynamic linq query that is needed in my application. 我一直在尝试解决应用程序中所需的动态linq查询的语法。

I have a dynamic query that the where clause needs to be specified to either 我有一个动态查询,其中需要将where子句指定为

  • GuidPrimaryKey is contained in a list of Guid OR GuidPrimaryKey包含在Guid OR列表中
  • GuidPrimaryKey is equal to an item in a list of Guid (using some type of for-loop) GuidPrimaryKey等于Guid列表中的一项(使用某种类型的for循环)

I have a Guid[] populated with over 5,000 keys. 我有一个Guid [],里面装有5,000多个键。 My Query is set up as 我的查询设置为

If I do this (as a test) it is successful 如果我这样做(作为测试)成功

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

as well as 以及

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

I have tried: data = data.where("GuidPrimaryKey.Contains(@0)",array); 我试过了: data = data.where("GuidPrimaryKey.Contains(@0)",array); but that gives an error: No applicable method 'Contains' exists in type 'Guid'. 但这会导致错误:类型'Guid'中不存在适用的方法'Contains'。

I also tried setting a loop to go through the elements in the array and set the where clause as a giant string, but that did not work either. 我还尝试设置循环以遍历数组中的元素,并将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);

This gives me the error message: No Property or field '1' exists in type 'DynamicClass1' 这给我错误消息:类型'DynamicClass1'中不存在属性或字段'1'

Any ideas? 有任何想法吗? I need to have the where clause build the query to check to see if the primary key (GuidPrimaryKey) exists in the list of keys (Guid[]). 我需要让where子句构建查询,以检查键列表(Guid [])中是否存在主键(GuidPrimaryKey)。

I'm not sure if this works in the standard Dynamic Linq library, but I just tried this is my open-source version , and it works well: 我不确定这是否可以在标准Dynamic Linq库中使用,但是我刚刚尝试过这是我的开源版本 ,并且效果很好:

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

This also works: 这也适用:

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

Here is a full unit test I wrote to confirm this: 这是我为确认这一点而编写的完整单元测试:

[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());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM