Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linq 构建lambda WHERE表达式以传递到方法_Linq_C# 4.0_Lambda_Odata - Fatal编程技术网

Linq 构建lambda WHERE表达式以传递到方法

Linq 构建lambda WHERE表达式以传递到方法,linq,c#-4.0,lambda,odata,Linq,C# 4.0,Lambda,Odata,我需要传入一个“where”lambda表达式,该表达式将在方法内部的LINQ查询中使用。问题是,在我进入方法之前,我不知道where值将与什么进行比较 现在,为了进一步解释和澄清我上面所说的一些内容,我将提出一个做作的例子 假设我有一个列表,我需要使用Products对象的productId属性将该列表缩小到单个记录。通常我会这样做: var product = productList.Where(p=>p.productId == 123).FirstOrDefault(); 现在更

我需要传入一个“where”lambda表达式,该表达式将在方法内部的LINQ查询中使用。问题是,在我进入方法之前,我不知道where值将与什么进行比较

现在,为了进一步解释和澄清我上面所说的一些内容,我将提出一个做作的例子

假设我有一个
列表
,我需要使用Products对象的
productId
属性将该列表缩小到单个记录。通常我会这样做:

var product = productList.Where(p=>p.productId == 123).FirstOrDefault();
现在更进一步-我需要将上述逻辑放入一个方法中,该方法不仅限于
列表
,而是一个
列表
,因此理想情况下,我会这样称呼它(我知道下面的内容行不通,这里只是为了说明我正在努力实现的目标):

需要注意的是,在我进入这个方法之前,X是未知的

最后,我需要指出,我收集的数据是OData
DataServiceQuery

因此,重新总结一下我的问题:我需要知道如何构造一个lambda“where”表达式,我可以将它传递到一个方法中,以及如何在LINQ查询中对一组对象使用它。

myMethod(productList,p=>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);
    }
静态void myMethod(列表,Func谓词,ref int x)
{
x=5;
var v=列表,其中(谓词);
foreach(v中的var i)
控制台。写入(i);
Console.ReadLine();
}
静态void Main(字符串[]参数)
{
列表x=新列表{1,2,3,4,5};
int z=0;
myMethod(x,p=>p==z,ref z);
}
但不确定它是否能完整地解决您的问题

myMethod(productList,p=>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);
    }
静态void myMethod(列表,Func谓词,ref int x)
{
x=5;
var v=列表,其中(谓词);
foreach(v中的var i)
控制台。写入(i);
Console.ReadLine();
}
静态void Main(字符串[]参数)
{
列表x=新列表{1,2,3,4,5};
int z=0;
myMethod(x,p=>p==z,ref z);
}

但不确定它是否整体解决了您的问题

您可以尝试使用免费LinqKit库()中的
PredicateBuilder

然后,您可以使用

PredicateBuilder predicate = PredicateBuilder.True<T>();
predicate = PredicateBuilder.And(predicate, p=> p.product_id == X);
PredicateBuilder predicate=PredicateBuilder.True();
谓词=谓词builder.And(谓词,p=>p.product\u id==X);
其中X为T型


您可以在where子句中使用此谓词,例如
.where(predicate)
,并返回IQueryable或返回谓词本身,其类型应为
表达式

,您可以尝试使用免费LinqKit库()中的
PredicateBuilder

然后,您可以使用

PredicateBuilder predicate = PredicateBuilder.True<T>();
predicate = PredicateBuilder.And(predicate, p=> p.product_id == X);
PredicateBuilder predicate=PredicateBuilder.True();
谓词=谓词builder.And(谓词,p=>p.product\u id==X);
其中X为T型


您可以在where子句中使用此谓词,例如
。where(谓词)
,并返回IQueryable或返回谓词本身,其类型将为
表达式

,如果您要查询
IEnumerable
,则首先需要确保比较有效。在这种情况下,您可以使对象实现一个接口,以确保它们支持比较

一旦您这样做了,您的方法就可以有一个通用约束来限制这些接口的输入。此时,您的方法可以接受Func,该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();
}
公共接口标识符
{
int Id{get;set;}
}
公共类产品:标识符
{
公共int Id{get;set;}
//其他东西
}
公共T GetMatch(IEnumerable集合,Func谓词),其中T:标识符
{
整数比较=5;
返回集合。其中(item=>predicate(item,comparison)).FirstOrDefault();
}
可以像这样调用:

var match = GetMatch<Identifier>(collection, (x, y) => x.Id == y);
var match=GetMatch(集合,(x,y)=>x.Id==y);
更新:
我修改了上面的代码,将一个比较参数

作为一个参数,如果您要查询一个
IEnumerable
,首先需要确保您的比较工作正常。在这种情况下,您可以使对象实现一个接口,以确保它们支持比较

一旦您这样做了,您的方法就可以有一个通用约束来限制这些接口的输入。此时,您的方法可以接受Func,该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();
}
公共接口标识符
{
int Id{get;set;}
}
公共类产品:标识符
{
公共int Id{get;set;}
//其他东西
}
公共T GetMatch(IEnumerable集合,Func谓词),其中T:标识符
{
整数比较=5;
返回集合。其中(item=>predicate(item,comparison)).FirstOrDefault();
}
可以像这样调用:

var match = GetMatch<Identifier>(collection, (x, y) => x.Id == y);
var match=GetMatch(集合,(x,y)=>x.Id==y);
更新:
我修改了上面的代码以引入一个比较参数

T always has productId属性?不,productId不总是属性。有时我可能有一个用户列表,所以它可能是UserId,或者可能是一组公司对象的companyId。不总是有productId属性?不,productId不总是属性。有时我可能会有一个用户列表,所以它可能是UserId,或者是一组公司对象的companyId。这个想法很有趣!如果你看到它在某个地方实现,你会认为它是一个黑客吗?还没有看到它实现,但它不是黑客,它是合法的从语法观点有趣的想法!如果你看到它在某个地方实现,你会认为它是一个黑客吗?还没有看到它实现,但它不是一个