【问题标题】:Build lambda expression dynamically动态构建 lambda 表达式
【发布时间】:2011-05-06 15:39:53
【问题描述】:
我正在尝试对对象集合进行动态排序。理想情况下,我希望它执行以下功能,我可以在运行时指定条件。
_group.OrderByDescending(rec => "rec.CalculatedRecord.GL.PropertyValue").Take(Convert.ToInt16(_filters.Value))
我尝试了无效的动态 linq。
var query = (from enumerable in _group
orderby "rec.CalculatedRecord.GL.PropertyValue"). descending
select enumerable).Take(5);
【问题讨论】:
标签:
linq
sorting
dynamic
lambda
linq-to-objects
【解决方案1】:
关于为什么第二个不应该工作的注释:您的枚举对象称为enumerable,但在您的字符串中,您仍在使用rec,就像之前的lambda一样。将字符串更改为使用 enumerable 而不是 rec 可能会缓解您的问题。
【解决方案2】:
OrderByDescending 方法采用Func<TSource, TKey> 参数。虽然您可以在此处插入 lambda(这是最常见的用例),但您也可以传入一个变量。可以根据您的逻辑动态分配变量。
我不得不推断您的类结构,但这里有一个基本示例:
public class Record
{
public CalculatedRecord CalculatedRecord { get; set; }
}
public class CalculatedRecord
{
public GL GL { get; set; }
}
public class GL
{
public PropertyValue PropertyValue1 { get; set; }
public PropertyValue PropertyValue2 { get; set; }
}
public class PropertyValue { }
那么你可以创建如下逻辑:
public class TestHarness
{
public void Test()
{
IEnumerable<Record> Group = new List<Record>();
//Simple flag
bool someCriteria = true;
//Define orderByFunc
Func<Record, PropertyValue> orderByFunc;
//Assign the order by function based on someCriteria
if (someCriteria)
{
orderByFunc = record =>
record.CalculatedRecord.GL.PropertyValue1;
}
else
{
orderByFunc = record =>
record.CalculatedRecord.GL.PropertyValue2;
}
//Execute OrderBy
var updated = Group.OrderByDescending(orderByFunc).Take(5);
}
}
但是,这不允许您在运行时动态生成 Func。为此,您需要使用表达式树构建Expression,然后对其进行编译。您可以按照Expression.Lambda and query generation at runtime, simplest "Where" example的步骤进行操作