【发布时间】:2012-10-30 01:40:17
【问题描述】:
我正在编写一组 LINQ 2 SQL 扩展方法。现在,我有一堆重复的方法,一个在 IEnumerable 集合上工作,另一个在 IQueryable 集合上工作。例如
public static IQueryable<X> LimitVisible(this IQueryable<X> items) {
return items.Where(x => !x.Hidden && !x.Parent.Hidden);
}
public static IEnumerable<X> LimitVisible(this IEnumerable<X> items) {
return items.Where(x => !x.Hidden && !x.Parent.Hidden);
}
我认为我需要这种重复,因为我希望能够在某些情况下保留 IQueryable 行为,以便将执行推迟到数据库。 这是一个正确的假设,还是单个 IEnumerable 方法(加上将输出转换为 IQueryable)有效?如果我确实需要两者,我不喜欢重复,所以我想将两者结合使用泛型方法
public static T LimitVisible<T>(this T items) where T : IEnumerable<X> {
return (T)items.Where(x => !x.Hidden && !x.Parent.Hidden);
}
除了我还想为其编写 LimitVisible 函数的 X 以外的其他类型(比如 Y 和 Z)之外,这是可行的。但我不会写
public static T LimitVisible<T>(this T items) where T : IEnumerable<Y> {
return (T)items.Where(y => !y.Hidden && !y.Parent.Hidden);
}
因为你可以基于泛型重载。我可以将这些方法放在不同的类中,但这似乎不是正确的解决方案。
有什么建议吗?也许我做出了不正确的假设,并且首先不需要 IQueryable 特定版本。
编辑:另一个选项
这是我过去用来避免重复的另一种模式
private static readonly Expression<Func<X, bool>> F = x => !x.Hidden && !x.Parent.Hidden;
public static IEnumerable<X> LimitVisible(this IEnumerable<X> e) {
return e.Select(W.Compile());
}
public static IQueryable<X> LimitVisible(this IQueryable<X> q) {
return q.Select(W);
}
这样做有什么危险吗?
【问题讨论】:
-
X、Y、Z 是否有用于
Hidden和Parent属性的通用接口或基类? -
不,它们是数据库中的不同表,恰好都有隐藏字段。