简体   繁体   中英

List<T> to implement IQueryable<T>

I'm trying to create a mock for my IRepository interface:

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

With this implementation:

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

But when I use it, I'm getting StackOverflow exception. How to implement this interface correctly to be able to use just a List as a repository?

Usage is very 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);
}

Here is screenshot of exception:

例外

The reason for your problem is that if you perform AsQueryable it checks if the object already implements IQueryable and if yes returns it.

Use new EnumerableQuery<T>(this) instead of AsQueryable which doesn't perform this check.


Workaround for .net 3.5:

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

First casts to IEnumerable<T> so the chosen Select method will be Enumerable.Select not Queryable.Select . The identity select will then return a new object that does not implement IQueryable<T> , so the check if it's implemented in AsQueryable fails.

Try using base.AsQueryable() instead of this.AsQueryable() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM