我需要传入一个“where”lambda表达式,它将在方法内的LINQ查询中使用。问题是,在进入方法之前,我不知道将比较哪个值。
现在进一步解释并澄清我上面所说的一些内容,我会想出一些人为的例子。
想象一下,我有一个List<Products>
,我需要使用Products对象的productId
属性将该列表缩小到单个记录。通常我会这样做:
var product = productList.Where(p=>p.productId == 123).FirstOrDefault();
现在更进一步 - 我需要将上述逻辑放入一个不限于List<Products>
的方法,而是List<T>
,所以理想情况下,我会称之为像这样(我知道下面的内容不起作用,只是在这里展示我想要实现的目标):
myMethod(productList, p => p.productId == X)
需要注意的是,在我进入方法之前,X不知道。
最后,为了它的价值,我需要指出我的数据集合是一个OData DataServiceQuery
。
所以,重新总结一下我的问题:我需要知道如何构造一个lambda“where”表达式,我可以将其传递给一个方法,以及如何在LINQ查询中对象集合中使用它。
答案 0 :(得分:2)
myMethod(productList,p =&gt; p.productId == X) - 你可以用这个技巧模仿
static void myMethod<T>(List<T> list, Func<T,bool> predicate, ref int x)
{
x = 5;
var v = list.Where(predicate);
foreach (var i in v)
Console.Write(i);
Console.ReadLine();
}
static void Main(string[] args)
{
List<int> x = new List<int> { 1, 2, 3, 4, 5 };
int z = 0;
myMethod(x, p => p == z, ref z);
}
但不确定它是否解决了整个问题
答案 1 :(得分:2)
首先,如果您要查询IEnumerable<T>
,则需要确保首先进行比较。在这种情况下,您可以使对象实现一个接口,以保证它们支持比较。
一旦这样做,您的方法就可以有一个通用约束来限制这些接口的输入。此时,您的方法可以使用Func,它可以传递给LINQ Where子句:
public interface Identifier
{
int Id { get; set; }
}
public class Product : Identifier
{
public int Id { get; set; }
//Other stuff
}
public T GetMatch<T>(IEnumerable<T> collection, Func<T, int, bool> predicate) where T : Identifier
{
int comparison = 5;
return collection.Where(item => predicate(item, comparison)).FirstOrDefault();
}
可以调用:
var match = GetMatch<Identifier>(collection, (x, y) => x.Id == y);
<强>更新强> 我修改了上面的代码以接受比较参数
答案 2 :(得分:0)
您可以尝试使用免费的LinqKit库中的PredicateBuilder
类(tutorial)。
然后,您可以使用
构造谓词PredicateBuilder predicate = PredicateBuilder.True<T>();
predicate = PredicateBuilder.And(predicate, p=> p.product_id == X);
其中X是T型。
您可以在诸如.Where(predicate)
之类的where子句中使用此谓词并返回IQueryable或返回类型为Expression<Func<T, bool>>
的谓词本身