LINQ过滤-优化

本文关键字:优化 过滤 LINQ | 更新日期: 2023-09-27 17:59:41

我进行了一次数据库访问,以获取实体列表。然后我想把这个列表分为两个列表,一个是未过期的实体(使用开始和结束),我称之为TopListings,另一个是常规列表,那些已经过期或开始/结束日期为null的实体(不是TopListings的实体)

我不完全确定哪个过滤被固定为两个列表,我应该先得到顶部列表,然后根据第二个不在顶部列表中的内容过滤第二个列表吗?

var listings = ListingAdapter.GetMapListings(criteria);
var topListings = listings.Where(x => x.TopStartDate >= DateTime.Now && x.TopExpireDate >= DateTime.Now);
//I AM NOT SURE WHAT THIS LINE SHOULD BE
var regularListings = listings.Where(x => x.TopStartDate < DateTime.Now || x.TopExpireDate < DateTime.Now || x.TopStartDate == null || x.TopExpireDate == null );

感谢

LINQ过滤-优化

您可能需要使用LookUp

像这样:

var lookup = listings.ToLookup(x => x.TopStartDate >= DateTime.Now && x.TopExpireDate >= DateTime.Now);
var topListings = lookup[true];
var regularListings = lookup[false]; // I assume everything not a topListing is a regular listing.

如果这还不够,你可以创建一个枚举

enum ListingType { Top, Regular, WhatEver };
...
var lookup = listings.ToLookUp(determineListingType); // pass a methoddelegate that determines the listingtype for an element.
...
var topListings = lookup[ListingType.Top];
var regularListings = lookup[ListingType.Regular];
var whateverListings = lookup[ListingType.WhatEver];

在这种情况下,使用循环可能会更容易,而不是使用Linq运算符:

var topListings = new List<Listing>();
var regularListings = new List<Listing>();
foreach (var x in listings)
{
    if (x.TopStartDate >= DateTime.Now && x.TopExpireDate >= DateTime.Now)
        topListings.Add(x);
    else
        regularListings.Add(x);
}

这也更有效,因为列表只枚举一次。

看一下'Except'运算符,让事情变得简单一点。不过,您可能需要先在topListings上添加一个.ToList()。

var regularListings = listings.Except(topListings);

http://blogs.msdn.com/b/charlie/archive/2008/07/12/the-linq-set-operators.aspx

使用直接的常规foreach循环。您可以一次遍历listing,并将项目添加到适当的集合中。如果你是LINQ类型的人,ForEach扩展就是你想要的:

var topListings = new List<Listing>();
var regularListings = new List<Listing>();
listing.ForEach(item=>{
                      if (x.TopStartDate < DateTime.Now 
                            ||       // I've inverted the condition, since it is faster-one or two conditions will be checked, instead of always two
                          x.TopExpireDate < DateTime.Now)
                        regularListings.Add(x);
                      else
                        topListings.Add(x);
                });