构建一个C#Linq帮助器

时间:2010-08-16 12:29:32

标签: c# linq filter linq-to-objects

我正在尝试使用Linq构建一个实用程序方法,它将帮助我进行常见的Linq-to-Objects搜索。

我有一个PropertyTbl对象,它引用了一个Address。 我有IEnumerable<PropertyTbl>。 我编写了一个带有IEnumerable<Address>的帮助器,一些搜索条件返回IEnumerable<Address>,迭代时会给我匹配的地址。

但是我无法弄清楚如何将两者插在一起,因为虽然我可以在我的IEnumerable<PropertyTbl>上执行.Select()来获取可枚举的地址,但我需要将结果设为IEnumerable<PropertyTbl>

这是我的帮助代码

    public static IEnumerable<Address> BuildAddressWhereClause(IEnumerable<Address> addresses, string value, AddressSearchOptions options)
    {
        string search = value.ToUpper();

        if ((options & AddressSearchOptions.Address1To4) == AddressSearchOptions.Address1To4)
        {
            addresses = addresses.Where(o => o.Address1.ToUpper().Contains(search)
                                             || o.Address2.ToUpper().Contains(search)
                                             || o.Address3.ToUpper().Contains(search)
                                             || o.Address4.ToUpper().Contains(search));
        }

        if ((options & AddressSearchOptions.City) == AddressSearchOptions.City)
        {
            addresses = addresses.Where(o => o.City.ToUpper().Contains(search));
        }

        if ((options & AddressSearchOptions.PostCode) == AddressSearchOptions.PostCode)
        {
            addresses = addresses.Where(o => o.PostCode.ToUpper().Contains(search));
        }

        return addresses;
    }

我想做的就是这个。

IEnumerable<PropertyTbl> properties = ...;

IEnumerable<PropertyTbl> filteredProperties = <use my address helper somehow>;

// this works but I need the properties as the result not just the addresses
IEnumerable<Address> filteredAddresses = AddressUtils.FilterAddresses(properties.Select(o => o.Address), "1 High Street", ...);

我可以通过将帮助程序代码直接放入正在加载/过滤属性的代码中来执行我想要的操作但是我无法重复使用它。

任何建议表示赞赏。

1 个答案:

答案 0 :(得分:2)

IEnumerable<PropertyTbl>不是IEnumerable<Address>,因此您需要某种方式访问​​Address的{​​{1}}字段(除非您更改PropertyTable采取BuildAddressWhereClause

这样的事情可以解决问题:

IEnumerable<PropertyTbl>

然后你像

一样调用它
public static IEnumerable<T> BuildAddressWhereClause<T>(IEnumerable<T> source, string value, AddressSearchOptions options, Func<T, Address> addressExtractor) { 
    string search = value.ToUpper(); 

    if ((options & AddressSearchOptions.Address1To4) == AddressSearchOptions.Address1To4) { 
        source = source.Where(o => addressExtractor(o).Address1.ToUpper().Contains(search) 
                                   || addressExtractor(o).Address2.ToUpper().Contains(search) 
                                   || addressExtractor(o).Address3.ToUpper().Contains(search) 
                                   || addressExtractor(o).Address4.ToUpper().Contains(search)); 
    } 

    if ((options & AddressSearchOptions.City) == AddressSearchOptions.City) { 
        source = source.Where(o => addressExtractor(o).City.ToUpper().Contains(search)); 
    } 

    if ((options & AddressSearchOptions.PostCode) == AddressSearchOptions.PostCode) { 
        source = source.Where(o => addressExtractor(o).PostCode.ToUpper().Contains(search)); 
    } 

    return source; 
}