我正在尝试为我的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);
}
以下是例外的截图:
答案 0 :(得分:29)
问题的原因在于,如果执行AsQueryable
,它会检查对象是否已经实现IQueryable
,如果是,则返回它。
使用new EnumerableQuery<T>(this)
代替不执行此检查的AsQueryable
。
.net 3.5的解决方法:
return ((IEnumerable<T>)this).Select(x=>x).AsQueryable()
首次投射到IEnumerable<T>
,因此所选的Select
方法将为Enumerable.Select
而不是Queryable.Select
。然后,身份选择将返回一个未实现IQueryable<T>
的新对象,因此检查它是否在AsQueryable
中实现失败。
答案 1 :(得分:1)
尝试使用base.AsQueryable()
代替this.AsQueryable()
。