6

受 MVC 店面启发,我正在进行的最新项目是在 IQueryable 上使用扩展方法来过滤结果。

我有这个界面;

IPrimaryKey
{
  int ID { get; }
}

我有这个扩展方法

public static IPrimaryKey GetByID(this IQueryable<IPrimaryKey> source, int id)
{
    return source(obj => obj.ID == id);
}

假设我有一个类 SimpleObj,它实现了 IPrimaryKey。当我有一个 SimpleObj 的 IQueryable 时,GetByID 方法不存在,除非我明确地将其转换为 IPrimaryKey 的 IQueryable,这不太理想。

我在这里错过了什么吗?

4

3 回答 3

13

如果做得对,它会起作用。cfeduke 的解决方案有效。但是,您不必使IPrimaryKey接口通用,实际上,您根本不必更改原始定义:

public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey
{
    return source(obj => obj.ID == id);
}
于 2008-09-17T17:15:31.257 回答
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);
于 2008-09-17T17:10:11.377 回答
2

由于泛型没有遵循继承模式的能力,因此这不起作用。IE。IQueryable<SimpleObj> 不在 IQueryable<IPrimaryKey> 的继承树中

于 2008-09-17T12:16:53.597 回答