【问题标题】:How to use the value from a property accessor LINQ expression in a Contains LINQ expression?如何在包含 LINQ 表达式中使用属性访问器 LINQ 表达式中的值?
【发布时间】:2013-04-24 00:18:54
【问题描述】:

我目前有一个用于访问对象属性的属性访问器的 LINQ 表达式。我现在需要构建一个 LINQ 表达式,该表达式将对谓词求值,以查看属性访问器的结果是否包含在列表中。

我已经看到,在大多数情况下,这种事情是使用 Expression 上的静态方法完成的,但是没有 Contains 或 In 可用作 Expression 上的静态方法,所以我不确定如何继续。

// A data object
internal class PersonDAL
{
    public int Age ( get; set; }
}

// A business object
public class Person
{
    private PersonDAL root { get; set; }

    public static Expression<Func<PersonDAL, int>> AgeExpression
    {
        get
        {
            return (root) => (root.Age);
        }
    }
}

现在我希望能够检查 AgeExpression 的值是否包含在年龄列表中。通常这类似于编写一个表达式来查看值列表是否包含我要检查的值,但我不知道如何将表达式的结果作为要搜索的值输入。

为了澄清一点,我试图弄清楚如何获取具有所有 Persons 的可查询对象,并仅获取未知表达式基于另一个表达式的值评估为 true 的 Persons。在我的示例案例中,未知访问器表达式正在查看一个人的年龄,它需要能够评估它是否包含在另一个可接受的年龄列表中。

【问题讨论】:

  • LINQ to Entities? LINQ 到对象? LINQ to XML?
  • @dtb - 目前底层 DAL 是 Codesmith PLINQO 模板的旧版本。我在 BOL 对象中手动构建了属性访问器,这些访问器指向 PLINQO 生成的 DAL 对象。
  • 如果没有动态表达式,您将如何进行查询?
  • AgeExpression 是静态的将不起作用。它需要访问实例变量。它应该是非静态的,还是我还缺少其他东西?
  • @Shlomo - 这是一个访问器表达式。它是一个输入 PersonDal 的特定实例并评估该实例的属性的函数。

标签: c# linq linq-expressions


【解决方案1】:

我不确定您为什么要使用表达式。我看不出你从他们那里得到了什么。但是如果修改AgeExpression的签名为Expression&lt;Func&lt;PersonDAL, int&gt;&gt;,就可以编译执行:

void Main()
{
    var pDal = new PersonDAL { Age = 3 };

    var ageFunc = Person.AgeExpression.Compile();
    var age = ageFunc(pDal);
    // age is 3
}

// Define other methods and classes here

// A data object
public class PersonDAL
{
    public int Age { get; set; }
}

// A business object
public class Person
{
    public Person(PersonDAL dal)
    {
        this.dal = dal;
    }

    private PersonDAL dal { get; set; }

    public static Expression<Func<PersonDAL, int>> AgeExpression
    {
        get
        {
            return (root) => (root.Age);
        }
    }
}

【讨论】:

  • 根本原因是试图构建一个 LINQ 兼容的过滤器框架。在运行时真正知道的只是定义如何解析特定值的表达式,然后我必须在过滤器中使用该值。编译和执行可能仍然是我需要的,所以我会试一试,看看我能得到什么。
  • 哦,另外,我确实已经有 Func 了,只是在将其转换为示例时错过了它。我不确定的是,当在我的其他表达式中访问它时,我会传递什么值以传递给它。举一个更完整的例子,假设我正在选择一个人的列表,他们的年龄在 10、20 和 30 的列表中。我可以将年龄添加到列表中并执行 AgeList.Contains(AgeAccessorFunc(??) ) 但我需要一些方法来将我选择的 Person 连接到 Contains 和访问器。
  • 我假设 AgeList 是某种形式的 IQueryable?那么查询看起来像这样:Persons.Where(p => AgeList.Contains(p.Age))?
  • 是的,类似的。我认为它实际上是以 p 作为参数的 Age 函数。很确定这适用于具体示例,但我不确定如果有其他标准,我将如何组装它。我认为这可能会延伸到另一个问题。
【解决方案2】:

这种问题也让我很困惑。请记住,您可以在 LINQ/lambda 表达式中访问局部变量:所以一个简单的 .where(x =&gt; x.value == AgeExpression) 应该会为您指明正确的方向

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 2018-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多