私のIRepository
インターフェイスのモックを作成しようとしています:
public interface IRepository<T> : ICollection<T>, IQueryable<T>
{
}
この実装では:
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;
}
}
}
しかし、それを使用すると、StackOverflow
例外が発生します。 List
だけをリポジトリとして使用できるように、このインターフェイスを正しく実装する方法は?
使い方はとても簡単
[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);
}
ここに例外のスクリーンショットがあります:
問題の理由は、AsQueryable
を実行すると、オブジェクトがすでにIQueryable
を実装しているかどうかがチェックされ、はいの場合はそれが返されるためです。
このチェックを実行しないAsQueryable
の代わりにnew EnumerableQuery<T>(this)
を使用します。
.net 3.5の回避策:
return ((IEnumerable<T>)this).Select(x=>x).AsQueryable()
最初にIEnumerable<T>
にキャストするため、選択されたSelect
メソッドはEnumerable.Select
ではなくQueryable.Select
になります。 ID選択は、IQueryable<T>
を実装しない新しいオブジェクトを返すため、AsQueryable
に実装されているかどうかのチェックは失敗します。
base.AsQueryable()
の代わりにthis.AsQueryable()
を使用してみてください。