2011-07-20 20 views
25

Estoy intentando crear una maqueta para mi IRepository interfaz:<T> para implementar IQueryable <T>

public interface IRepository<T> : ICollection<T>, IQueryable<T> 
{ 
} 

Con esta aplicación:

public class RepositoryFake<T> : List<T>, IRepository<T> 
{ 
    public Expression Expression 
    { 
     get 
     { 
      return this.AsQueryable().Expression; 
     } 
    } 

    public Type ElementType 
    { 
     get 
     { 
      return this.AsQueryable().ElementType; 
     } 
    } 

    public IQueryProvider Provider 
    { 
     get 
     { 
      return this.AsQueryable().Provider; 
     } 
    } 
} 

Pero cuando lo uso, me estoy haciendo StackOverflow excepción. ¿Cómo implementar esta interfaz correctamente para poder usar solo un List como repositorio?

uso es muy sencillo

[Test] 
public void Test() 
{ 
    RepositoryFake<User> users = new RepositoryFake<User>(); 
    users.Add(new User()); 

    List<User> list = (from user in users 
       where user.Id == "5" 
       select user).ToList(); 

    Assert.That(list, Is.Empty); 
} 

Aquí es pantalla de excepción:

Exception

+2

"Pero cuando lo uso", ¿nos muestran el código? Muéstranos el rastro de pila? – cdhowie

+0

¿Qué estás tratando de hacer? Mi mejor suposición es que estás esperando algo de magia. El comportamiento es completamente esperado. – leppie

Respuesta

29

La razón de su problema es que si se realiza AsQueryable comprueba si el objeto ya implementa IQueryable y si es que lo devuelve.

Use new EnumerableQuery<T>(this) en lugar de AsQueryable que no realiza esta comprobación.


Solución para .NET 3.5:

return ((IEnumerable<T>)this).Select(x=>x).AsQueryable() 

Primero arroja a IEnumerable<T> por lo que el Select método elegido será Enumerable.Select no Queryable.Select. La selección de identidad devolverá un nuevo objeto que no implementa IQueryable<T>, por lo que la comprobación si se implementa en AsQueryable falla.

+0

Tiene contructor protegido? .. – Sly

+0

El constructor que toma un 'IEnumerable ' es público. Compruebe http://msdn.microsoft.com/en-us/library/cc190806.aspx Al menos en .net 4 – CodesInChaos

+0

@CodeInChaos: nuevo en .NET 4. – leppie

1

Intente utilizar base.AsQueryable() en lugar de this.AsQueryable().

+0

La clase base no tiene dicha extensión – Sly

+0

No ayudaría de todos modos ya que la comprobación si 'IQueryable ' ya está implementado utiliza el tipo de tiempo de ejecución. Este no es un método virtual. – CodesInChaos

Cuestiones relacionadas