IEnumerable <t>过滤

时间:2017-07-26 12:23:33

标签: c#

我们假设我有以下对象:

系统:

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
  6. 我可以写其他条件,但我认为你明白我的观点。当SystemDto中的字段数量增加时,条件会增加。 我的问题是过滤方法应该是什么样的?我不认为有一个具有所有参数的方法是个好主意,因为可能会发生我必须将null放入不需要的字段,然后在正文中检查它是否被提供。当我有一个包含20个或更多字段的对象时,它会有很多行。

    - 编辑

    @Henric我认为你的答案是我需要的,但我有一个问题。我有IRepository和IService接口。我没有魔杖从数据源中提取所有记录并在使用之前对其进行过滤。如果我想在我有TSource = System的Repository类中过滤它,但是在Service类中我会有TSource = SystemDto。我将以某种方式映射TSources。这可能吗?

1 个答案:

答案 0 :(得分:1)

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

///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');

抱歉英语很差。