2012-02-13 79 views
3

我正在研究一种扩展方法来为多个实体提供过滤功能。涉及的实体类型不同,但具有可以搜索的共同字段。创建通用扩展方法来提供过滤功能

下面是目前的工作,但我想知道这是否可以“泛化”,以便从泛型到显式类型的转换不需要发生?

public static IQueryable<T> PriceLow<T>(this IQueryable<T> query, decimal? priceLow) 
{ 
    if (typeof(T) == typeof(Entity1)) 
    { 
     var innerQuery = (IQueryable<Entity1>) query; 
     var results = priceLow.HasValue ? innerQuery.Where(o => (o.ListPrice > priceLow.Value)) : innerQuery; 
     return (IQueryable<T>) results; 
    } 

    if (typeof(T) == typeof(Entity2)) 
    { 
     var innerQuery = (IQueryable<Entity2>)query; 
     var results = priceLow.HasValue ? innerQuery.Where(o => (o.ListPrice > priceLow.Value)) : innerQuery; 
     return (IQueryable<T>)results; 
    } 

    return null; 
} 

用法示例:

var foo = _repository.GetAllEntity1().PriceLow(_searchCritera.PriceLow); 

回答

3

如果您可以更改这两个实体类型以实现具有共享属性/方法的通用接口,那么您可以使用泛型类型约束。这也适用于共享基类。

做到这一点,然后你的签名看起来像这样(搞乱不再赘述):

public static IQueryable<T> PriceLow<T>(...) 
    where T : ICommonInterface 
+0

感谢保罗,知道如何在方法中指定公共基类(其中T:ICommonInterface) – Jesse 2012-02-13 16:34:56

2

如何使你的实体从保存的搜索领域一个基本类型继承。这样你的过滤方法只需要知道一个基类型。

+0

如果通过仅使其基本类型工作来删除通用性,则基本上会阻止进一步的链接。由于它将返回基类型的'IQueryable',因此需要强制转换特定于其中一个子类型的调用。 – 2012-02-13 05:56:20

1

一种方法是定义一个接口,并添加接口的类继承的事情之一。界面不需要包含任何东西。它可以被用作标记。

然后让你的扩展方法需要参数就是那个接口。

+1

标记接口不起作用,因为代码实际上使用的不仅是“对象”的属性' – 2012-02-13 05:43:48

+0

啊,你是对的。所以它看起来像你需要添加一些常见的实现到该接口。 – 2012-02-13 05:49:02