使 LINQ 扩展方法适用于我的班级
Posted
技术标签:
【中文标题】使 LINQ 扩展方法适用于我的班级【英文标题】:Make LINQ extension methods apply to my class 【发布时间】:2013-10-16 21:51:33 【问题描述】:我有一个 Repository 类,作为方法 FromStore<TEntity>
如下:
IQueryable<TEntity> FromStore<TEntity>() where TEntity : class;
使用它,我可以执行以下操作:
MyRepository.FromStore<DatabaseModel>().SingleOrDefault(dm => dm.Id = Id);
现在,我认为当我可以直接提供 SingleOrDefault 方法时让类的用户调用 FromStore
是愚蠢的(您只需要指定泛型类型参数,而不是像通常那样推断它案例)。
所以,我写了一个方法如下:
public TEntity SingleOrDefault<TEntity>(Expression<Func<TEntity, bool>> filter) where TEntity : class
return FromStore<TEntity>().SingleOrDefault(filter);
太棒了!现在我可以这样做了:
MyRepository.SingleOrDefault<DatabaseModel>(dm => dm.Id = Id);
但是,我想对所有 linq 扩展方法执行相同的操作。 目前我能想到的唯一方法是在我的类上为每个 linq 方法创建类似的包装器方法。
这看起来很傻,肯定有更好的方法吗?
我在想我能否以某种方式让我的 Repository
类继承 linq 扩展方法扩展的类,但它们扩展了 IQueriable<T>
。我的班级没有实现这一点,因为存储库中不仅有一个 T
。
即使我无法为特定的T
实现IQueryable<T>
,我能否以某种方式将 linq 扩展方法应用于我的班级?
【问题讨论】:
更复杂的是,存储库实际上实现了IRepository
,这是 API 的用户将看到的。所以我认为扩展方法必须在那里应用(不知何故??)。如果有没有接口的解决方案,但我会感兴趣。
我不认为你可以做到这一点,除非有某种方式使用dynamic
。任何解决方案都可能比要求您的客户致电FromStore
更麻烦。
认为可能是这样。如果我能实现IQuerable<>
(没有指定T
)就好了!不过,我会等着看是否有人有其他想法。
如果您知道您可能需要的所有TEntities
,您可以为每个具体类显式实现IQueryable<TEntity>
。但是,如果不先明确地转换您的存储库,您仍然无法使用 Linq
扩展方法,这在一定程度上违背了目的。
我非常努力地设想一个具有 generic 方法 Something<T>
的 non-generic 类,而无需声明该方法本身...我不能:(
【参考方案1】:
您可以将其实现为存储库接口的扩展方法。
public static class RepositoryExtensions
public static TEntity SingleOrDefault<TEntity>(
this IRepository repository,
Expression<Func<TEntity, bool>> filter
)
return repository.FromStore<TEntity>().SingleOrDefault(filter);
【讨论】:
感谢您的回答。可能我通过提到接口混淆了事情。我想知道是否可以避免为每个 linq 扩展方法编写类似上面的内容。 我想为了做到这一点,您需要编写自己的 linq 提供程序。这需要implementing a Query Provider。 嗯,好的。不过,我真的可以理解它的外观,同时能够自动使用扩展方法。IQueryable(T)
在Queryable
中有自己独立的扩展方法。底层表达式树 (IQueryable.Expression
) 使用方法调用 (Where
、GroupBy
、OrderBy
、Select
等) 及其参数构建,您可以使用这些参数来塑造数据。
我了解查询提供程序是如何工作的(在基本层面上),但据我了解,我最终还是会得到一个具有创建查询方法的存储库(现在是一个查询提供程序)。对我来说,这似乎与我现在的 fromstore 方法相同。一定有我遗漏的东西。以上是关于使 LINQ 扩展方法适用于我的班级的主要内容,如果未能解决你的问题,请参考以下文章
如何获取 Roslyn 中 NamedTypeSymbol 的所有适用方法,包括扩展方法?