web-dev-qa-db-fra.com

Liste <T> pour implémenter IQueryable <T>

J'essaie de créer une maquette pour mon interface IRepository:

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

Avec cette implémentation:

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;
        }
    }
}

Mais lorsque je l'utilise, j'obtiens une exception StackOverflow. Comment implémenter correctement cette interface pour pouvoir utiliser uniquement une List en tant que référentiel?

L'utilisation est très simple

[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);
}

Voici une capture d'écran de l'exception:

Exception

25
Sly

La raison de votre problème est que si vous exécutez AsQueryable, il vérifie si l’objet implémente déjà IQueryable et si yes le renvoie.

Utilisez new EnumerableQuery<T>(this) au lieu de AsQueryable qui n’effectue pas cette vérification.


Solution de contournement pour .net 3.5:

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

Les premiers lancements sur IEnumerable<T> de sorte que la méthode Select choisie sera Enumerable.Select et non Queryable.Select. La sélection d'identité renverra alors un nouvel objet qui n'implémentera pas IQueryable<T>. Par conséquent, la vérification de son implémentation dans AsQueryable échoue.

29
CodesInChaos

Essayez d’utiliser base.AsQueryable() au lieu de this.AsQueryable().

1
Daniel A. White