【问题标题】:Building a Dynamic Linq Query using Equals and an Array使用 Equals 和数组构建动态 Linq 查询
【发布时间】:2014-06-10 12:57:03
【问题描述】:

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

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

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

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

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

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[]) 中。

【问题讨论】:

  • 你能不能只做 data.Any 并使用你知道的表达方式?
  • @EricScherrer 不是 Dynamic Linq Contains 中的 Any 子句吗?如果是这样,则如上所述,这不起作用。
  • 如果动态表达式找到任何匹配项,data.any 将返回 true。因此,如果您放置 data = data.any("GuidPrimaryKey.Equals(@0) OR GuidPrimaryKey.Equals(@1),array[0], array[1]); 这可能会起作用。如果您包含您正在尝试的对象查询我将在VS中仔细查看。
  • @EricScherrer 我会试一试,但是有超过 5,000 个键取决于构建查询的标准,因此我需要将参数构建为变量或数组。关于如何实现这一点的任何想法?
  • 你搞错了。 guid 不包含数组,您想知道数组是否包含 GUID。我不熟悉动态 linq,但只是一个非常疯狂的猜测,尝试:data = data.where("@0.Contains(GuidPrimaryKey)",array);

标签: c# linq where dynamic-linq


【解决方案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());
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多