使用变量访问Linq属性

10

假设我有一个类如下:

public class Foo
{
    public string Title {get;set;}
}

现在,假设我有一个 public List<Foo> myList,我想用 Linq 进行筛选,如下所示:

var x = myList.Where(f => f.Title == myValue);

到目前为止,一切都很清晰明了。

但是如何通过变量访问属性呢?类似这样:

string myProperty = "Title";

var x = myList.Where(f => f.myProperty == myValue);
5个回答

22
你可以编写扩展方法。
public static class MyExtensions
{
    public static object GetProperty<T>(this T obj, string name) where T : class
    {
        Type t = typeof(T);
        return t.GetProperty(name).GetValue(obj, null);
    }
}

并且像这样使用它

var x = myList.Where(f => f.GetProperty("Title") == myValue);

4

LINQ不适用于这种情况。LINQ是一种流畅的接口,用于操作集合。通过文本表示访问成员使用反射完成。

object GetProperty(Foo f, string propertyName) {
  var type = typeof(Foo);
  var propInfo = type.GetProperty(propertyName);
  return propInfo.GetValue(f, null);
}

2
如果您需要动态地即时编写查询,可以使用Microsoft提供的LINQ动态查询库进行操作:

该示例展示了一种在运行时动态地组合LINQ语句的技术。

在您的代码中引用该库即可:

using System.Linq.Dynamic;

您的查询应该是这样的:
// You can use a string as the argument for the Where method
// meaning you can compose this string dynamically
string myProperty = "Title";
var x = myList.Where(myProperty + " = " + myValue);

在查询字符串中使用占位符也是可能的,这有助于提高可读性(某种程度上):

var x = myList.Where("@0 = @1", myProperty, myValue);

请参考Scott Guthrie的这篇文章:Dynamic LINQ Part 1:使用LINQ动态查询库我认为从来没有第二部分...注意:您必须编译Microsoft的示例代码并引用构建的程序集,或者将代码包含在您自己的项目中。

嗯,为什么它不是标准的 .net 框架的一部分呢?看起来很诱人。 - Surjit Samra
@SurjitSamra 在第一次 LINQ 发布时(Visual Studio 2008,C# 3.0),微软编写了许多示例来帮助每个人理解 LINQ 的强大功能。这只是其中之一的示例,它本身可能非常有用,但可能仅限于框架的一部分。 - Michiel van Oosterhout
如果我处于这种情况,坦率地说,我会更倾向于LB的答案。 - Surjit Samra

2

我知道这是一个旧的帖子,但这里有另一种方法可以实现。如果你需要在循环中执行此操作,这种方式具有显著的速度优势。我已经将“func”函数的结果转换为对象,使其更具通用性。

        var p = Expression.Parameter(typeof(string));
        var prop = Expression.Property(p, "Length");
        var con = Expression.Convert(prop, typeof(object));
        var exp = Expression.Lambda(con, p);
        var func = (Func<string, object>)exp.Compile();

        var obj = "ABC";
        int len = (int)func(obj);

在原问题中,该代码被用于linq中,因此速度可能很快。如果构建正确,也可以直接在where子句中使用"func"。

        class ABC
        {
            public string Name { get; set; }
        }

        var p = Expression.Parameter(typeof(ABC));
        var prop = Expression.Property(p, "Name");
        var body = Expression.Equal(prop, Expression.Constant("Bob"));
        var exp = Expression.Lambda(body, p);
        var func = (Func<ABC, bool>)exp.Compile();

        ABC[] items = "Fred,Bob,Mary,Jane,Bob".Split(',').Select(s => new ABC() { Name = s }).ToArray();
        ABC[] bobs = items.Where(func).ToArray();

0

你不能在这里使用 LINQ Microsoft 的动态查询,以下是示例代码

 var query =  db.Customers.Where("City == @0 and Orders.Count >= @1", "London", 10).
            OrderBy("CompanyName").
            Select("New(CompanyName as Name, Phone)"); 

1
你为什么链接到许可协议? - Cody Gray

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接