将多个条件传递给 LINQ FirstOrDefault 方法

Posted

技术标签:

【中文标题】将多个条件传递给 LINQ FirstOrDefault 方法【英文标题】:passing Multiple conditions to LINQ FirstOrDefault Method 【发布时间】:2016-06-30 13:52:55 【问题描述】:

我有一个gelolocations 的列表。我想在列表中执行 2 个条件并选择满足这些条件的条件。我不知道该怎么做。

public class GeolocationInfo

    public string Postcode  get; set; 

    public decimal Latitude  get; set; 

    public decimal Longitude  get; set; 


var geolocationList = new List<GeolocationInfo>(); // Let's assume i have data in this list

我想在这个列表上执行多个条件geolocationList

我想在此列表中使用FirstOrDefault,条件是PostCode 属性与提供的属性匹配且经度、纬度不为空。

    geolocationList .FirstOrDefault(g => g.PostCode  == "AB1C DE2"); 
// I want to add multiple conditions like  g.Longitude != null && g.Lattitude != null in the same expression

我想在外面构建这个conditions,并将它作为参数传递给FirstOrDefault。例如,构建一个 Func&lt;input, output&gt; 并将其传递给。

【问题讨论】:

您是否尝试在 FirstOrDefault 中的注释中添加条件? 我试过了,它可以工作,但我的目标是不要将所有条件都放在FirstOrDefault 中。我举了equals比较的简单例子。我有非常复杂的条件。它们绝对不可读。我想用这些条件构建一个expression 并将它们传递给FirstOrDefault 【参考方案1】:

你已经给出了自己的答案:

geoLocation.FirstOrDefault(g => g.Longitude != null && g.Latitude != null);

【讨论】:

【参考方案2】:

FirstOrDefault 可以采用复杂的 lambda,例如:

geolocationList.FirstOrDefault(g =&gt; g.PostCode == "ABC" &amp;&amp; g.Latitude &gt; 10 &amp;&amp; g.Longitude &lt; 50);

【讨论】:

你甚至可以偷偷摸摸:geolocationList.FirstOrDefault(g =&gt; if (g.PostCode.contains("A")) return true; // always accept post codes containing "A" return g.Latitude &gt; 10; ) 有什么方法可以在外部使用Func&lt;&gt; 构建此表达式并将其作为参数传递给FirstOrDefault 如果不想使用匿名函数,可以试试geolocationList.FirstOrDefault(g =&gt; IsParameterOk(g));bool IsParameterOk(GeolocationInfo g) /* logic here */ 当然,你可以定义自己的函数public bool FirstOrDefaultFilter(GeolocationInfo geolocationInfo)然后直接使用它:geolocationList.FirstOrDefault(FirstOrDefaultFilter) @KamilT 在这种情况下我们不需要 lambda g =&gt; IsParameterOk(g)IsParameterOk 的签名与需要 lambda 的 Func&lt;GeolocationInfo, bool&gt; 相同。【参考方案3】:

感谢您的回复。它帮助我以正确的方式思考。

我确实喜欢这个。

Func<GeolocationInfo, bool> expression = g => g.PostCode == "ABC" &&
                                              g.Longitude != null &&
                                              g.Lattitude != null;
geoLocation.FirstOrDefault(expression);

它成功了,代码也好多了。

【讨论】:

如果问题得到解决,请标记问题的答案。【参考方案4】:
public static TSource FirstOrDefault<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, bool> predicate
)

predicate 类型:System.Func 一个函数来测试每个 条件的元素。

因此您可以使用任何获取TSource 并返回bool 的Func

//return all
Func<GeolocationInfo, bool> predicate = geo => true;

//return only geo.Postcode == "1" and geo.Latitude == decimal.One
Func<GeolocationInfo, bool> withTwoConditions = geo => geo.Postcode == "1" && geo.Latitude == decimal.One;

var geos = new List<GeolocationInfo>

    new GeolocationInfo(),
    new GeolocationInfo Postcode = "1", Latitude = decimal.One,
    new GeolocationInfo Postcode = "2", Latitude = decimal.Zero
;

//using
var a = geos.FirstOrDefault(predicate);
var b = geos.FirstOrDefault(withTwoConditions);

【讨论】:

以上是关于将多个条件传递给 LINQ FirstOrDefault 方法的主要内容,如果未能解决你的问题,请参考以下文章

如何将 linq var 数据类型传递给方法? [复制]

将 Func 传递给 Linq 到实体 Sum(..)

如何在数字字段的条件下将逗号分隔的数字字符串传递给存储过程?

如何将 Predicate<T> 传递给 Linq to SQL 中的 Where() 方法?

LINQ Join 与 On 子句中的多个条件

在 PL/SQL 存储过程中将多个变量传递给 WHERE 条件