受到MVC店面的启发,我正在研究的最新项目是使用IQueryable上的扩展方法来过滤结果。
我有这个界面;
IPrimaryKey
{
int ID { get; }
}
我有这个扩展方法
public static IPrimaryKey GetByID(this IQueryable<IPrimaryKey> source, int id)
{
return source(obj => obj.ID == id);
}
假设我有一个实现IPrimaryKey的类SimpleObj。当我有一个SimpleObj的IQueryable时,GetByID方法不存在,除非我明确地转换为IPrimaryKey的IQueryable,这是不太理想的。
我在这里错过了什么吗?
答案 0 :(得分:13)
如果做得好,它就有效。 cfeduke的解决方案有效。但是,您不必使IPrimaryKey
接口通用,事实上,您根本不需要更改原始定义:
public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey
{
return source(obj => obj.ID == id);
}
答案 1 :(得分:4)
编辑:Konrad的解决方案更好,因为它更简单。下面的解决方案有效但仅在类似于ObjectDataSource的情况下才需要,其中通过反射检索类的方法而不会继承继承层次结构。显然这不会发生在这里。
这是可能的,当我设计一个用于处理ObjectDataSource的自定义实体框架解决方案时,我必须实现类似的模式:
public interface IPrimaryKey<T> where T : IPrimaryKey<T>
{
int Id { get; }
}
public static class IPrimaryKeyTExtension
{
public static IPrimaryKey<T> GetById<T>(this IQueryable<T> source, int id) where T : IPrimaryKey<T>
{
return source.Where(pk => pk.Id == id).SingleOrDefault();
}
}
public class Person : IPrimaryKey<Person>
{
public int Id { get; set; }
}
使用片段:
var people = new List<Person>
{
new Person { Id = 1 },
new Person { Id = 2 },
new Person { Id = 3 }
};
var personOne = people.AsQueryable().GetById(1);
答案 2 :(得分:2)
由于泛型不具备遵循继承模式的能力,因此无法工作。即。 IQueryable的&LT; SimpleObj&GT;不在IQueryable&lt; IPrimaryKey&gt;
的继承树中