Pergunta

Inspirado na loja do MVC, o projeto mais recente em que estou trabalhando é usar métodos de extensão no iQueryable para filtrar os resultados.

Eu tenho essa interface;

IPrimaryKey
{
  int ID { get; }
}

E eu tenho este método de extensão

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

Digamos que eu tenho uma aula, SimpleObj, que implementa o iPrimaryKey. Quando eu tenho um iQueryabj, o método getById não existe, a menos que eu seja explicitamente lançado como um iQueryable do iPrimaryKey, o que é menos do que o ideal.

Estou perdendo alguma coisa aqui?

Foi útil?

Solução

Funciona, quando feito certo. A solução da CFEDUKE funciona. No entanto, você não precisa fazer o IPrimaryKey Interface genérica, de fato, você não precisa alterar sua definição original:

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

Outras dicas

Editar: KonradA solução é melhor porque é muito mais simples. A solução abaixo funciona, mas é necessária apenas em situações semelhantes ao ObjectDataSource, onde um método de classe é recuperado através da reflexão sem aumentar a hierarquia da herança. Obviamente, isso não está acontecendo aqui.

Isso é possível, tive que implementar um padrão semelhante quando projetei uma solução de estrutura de entidade personalizada para trabalhar com o 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; }
}

Trecho de uso:

var people = new List<Person>
{
    new Person { Id = 1 },
    new Person { Id = 2 },
    new Person { Id = 3 }
};

var personOne = people.AsQueryable().GetById(1);

Isso não pode funcionar devido ao fato de que os genéricos não têm a capacidade de seguir padrões de herança. ou seja. IQueyableu003CSimpleObj> não está na árvore de herança de iQueryableu003CIPrimaryKey>

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top