按变量的Linq访问属性
本文关键字:访问 属性 Linq 变量 | 更新日期: 2023-09-27 18:19:38
假设我有一个类:
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);
您可以编写一个扩展方法
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);
这不是LINQ用于的情况类型。LINQ是一个操作集合的流畅接口。通过文本表示访问成员是通过反射完成的。
object GetProperty(Foo f, string propertyName) {
var type = typeof(Foo);
var propInfo = type.GetProperty(propertyName);
return propInfo.GetValue(f, null);
}
如果您需要动态地编写查询,可以使用LINQ动态查询库,这是Microsoft:的一个示例
此示例显示了在在运行时动态飞行。
参考代码中的库:
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的这篇文章:动态LINQ第1部分:使用LINQ动态查询库(我认为从来没有第2部分…)
注意:您必须从Microsoft编译示例代码并引用生成的程序集,或者您可以将代码包含在自己的项目中
我知道这是一个旧线程,但这里有另一种方法。如果你需要在循环中完成,这有一个明显更快的优势。我已经将"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();
您不能使用微软的linq动态查询这是的样本代码
var query = db.Customers.Where("City == @0 and Orders.Count >= @1", "London", 10).
OrderBy("CompanyName").
Select("New(CompanyName as Name, Phone)");