IEnumerable的过滤

问题描述:

假设我有对象,如下面:IEnumerable的<T>过滤

系统:

public class SystemDto 
{ 
    public int Id { get; set; } 
    public string Ip { get; set; } 
    public string Url { get; set; } 
    public RegionDto Region { get; set; } 
    public ApplicationDto Application { get; set; } 
    public bool Status { get; set; } 
} 

应用:

public class ApplicationDto 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

地区:

public class RegionDto 
{ 
    public string Name { get; set; } 
} 

现在让我们假设我有IEnumerable<SystemDto> 我想查询在不同的条件下,这个对象:

  1. 通过RegionDto.Name
  2. 通过IEnumerable<RegionDto.Name>
  3. 通过IEnumerable<RegionDto.Name>IEnumerable<ApplicationDto.Name>
  4. 通过RegionDto.NameIEnumerable<ApplicationDto.Name>
  5. 通过RegionDto.NameApplicationDto.Name

我可以写其他条件,但我认为你明白了我的观点。当SystemDto中的字段数量增加时,条件会增加。 我的问题是过滤方法应该是什么样子?我不认为有一个方法具有所有参数是好主意,因为它可能会发生,我将不得不把null不需要的字段,然后在身体检查是否提供。当我有一个具有20个或更多字段的对象时,它也会有很多行。

- 编辑

@Henric我认为你的答案是什么,我需要,但我有一个问题。我有IRepository和IService接口。我不想从数据源中提取所有记录,并在即将使用之前对其进行过滤。如果我想在存储库类中对其进行过滤,但是在服务类中,我将拥有TSource = SystemDto。我将不得不以某种方式映射TSources。这可能吗?

+1

这有帮助吗? https://msdn.microsoft.com/library/bb534803(v=vs.110).aspx – Henrik

+2

你需要一个过滤器方法吗?你不能简单地调用列表中的“Where”并指定当时要过滤的属性吗?另一种方法是编写一个包含所有可选参数的方法,每个参数的默认值为'null'。然后你可以在你每次打电话时提供你想要的。 – jmcilhinney

所以,也许这会有所帮助:

///Your Extensions class 
public static class MyExtensions 
{ 
    public static IEnumerable<T> Filter<T> (this IEnumerable<T> src, params Func<T, bool>[] predicates) 
    { 
     IEnumerator<T> enumerator = src.GetEnumerator(); 

     while (enumerator.MoveNext()) 
      if (predicates.All(condition => condition(enumerator.Current))) 
       yield return enumerator.Current; 
    } 

用法:

myList = myList.Filter(x => x.Region.Name == "someRegionName", 
         x => x.Application.Name == "someAppName" 
         /*And the list goes on(for the ones you want, duhh)*/ 
); 

或者只是使用什么样的LINQ已经有了:

myList = myList.Where(x => x.Region.Name == "someRegionName" && 
          x.Application.Name == "someAppName" 
          /*And the list goes on(for the ones you want, duhh again)*/ 
); 

或者,如果您有默认的过滤器,可以使用默认过滤器创建扩展方法类,以避免重写大量重复过滤器。

public static IEnumerable<MyClass> WhereDefaulted(this IEnumerable<MyClass> src, Func<MyClass,bool> predicate) 
{ 
    return src.Where(x => predicate(x) && 
          x.Some.Property == "someValue" && 
          x.Other.Property == 12); 
} 

,然后使用它:

myList = myList.WhereDefaulted(x => x.Some.Other.Property == 'l'); 

对不起,我英文不好。