Создание динамического запроса Linq с использованием Equals и массива

Я пытался решить синтаксис для динамического запроса linq, который необходим в моем приложении.

У меня есть динамический запрос, для которого необходимо указать предложение where.

  • GuidPrimaryKey содержится в списке Guid ИЛИ
  • GuidPrimaryKey равен элементу в списке Guid (с использованием некоторого типа цикла for)

У меня есть Guid[], содержащий более 5000 ключей. Мой запрос настроен как

Если я сделаю это (в качестве теста), это будет успешным

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);

Это дает мне сообщение об ошибке: Нет свойства или поля "1" не существует в типе "DynamicClass1"

Есть идеи? Мне нужно, чтобы предложение where создавало запрос, чтобы проверить, существует ли первичный ключ (GuidPrimaryKey) в списке ключей (Guid[]).


person EvanGWatkins    schedule 10.06.2014    source источник
comment
Можете ли вы просто сделать data.Any и использовать выражения, которые, как вы знаете, работают?   -  person Eric Scherrer    schedule 10.06.2014
comment
@EricScherrer не является предложением Any в Dynamic Linq содержит? Если это так, это не работает, как указано выше.   -  person EvanGWatkins    schedule 10.06.2014
comment
data.any вернет true, если динамическое выражение найдет совпадения. Итак, если вы поместите data = data.any(GuidPrimaryKey.Equals(@0) OR GuidPrimaryKey.Equals(@1),array[0], array[1]); это может сработать. Если вы включите объекты, которые вы пытаетесь запросить, я повнимательнее рассмотрю VS.   -  person Eric Scherrer    schedule 10.06.2014
comment
@EricScherrer Я попробую, однако существует более 5000 ключей, зависящих от критериев построения запроса, поэтому мне нужно, чтобы параметры были встроены либо в виде переменной, либо в виде массива. Любые идеи о том, как это сделать?   -  person EvanGWatkins    schedule 10.06.2014
comment
У тебя наоборот. GUID не содержит массив, вы хотите знать, содержит ли массив GUID. Я не знаком с динамическим linq, но просто очень дикая догадка, попробуйте: data = data.where("@0.Contains(GuidPrimaryKey)",array);   -  person Robert McKee    schedule 11.06.2014


Ответы (1)


Я не уверен, работает ли это в стандартной библиотеке Dynamic Linq, но я только что попробовал это мой открытый -исходная версия, и она работает хорошо:

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());
}
person Nathan A    schedule 11.07.2014