列表实现 IQueryable
我正在尝试为我的 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);
}
这是异常的屏幕截图:
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:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题的原因是,如果您执行 AsQueryable ,它会检查对象是否已经实现了 IQueryable ,如果是,则返回它。
使用
new EnumerableQuery(this)
而不是AsQueryable
,后者不执行此检查。.net 3.5 的解决方法:
首先转换为
IEnumerable
,因此所选的Select
方法将是Enumerable.Select
而不是Queryable。选择
。然后,身份选择将返回一个未实现IQueryable
的新对象,因此检查它是否在AsQueryable
中实现的检查失败。The reason for your problem is that if you perform
AsQueryable
it checks if the object already implementsIQueryable
and if yes returns it.Use
new EnumerableQuery<T>(this)
instead ofAsQueryable
which doesn't perform this check.Workaround for .net 3.5:
First casts to
IEnumerable<T>
so the chosenSelect
method will beEnumerable.Select
notQueryable.Select
. The identity select will then return a new object that does not implementIQueryable<T>
, so the check if it's implemented inAsQueryable
fails.尝试使用
base.AsQueryable()
而不是this.AsQueryable()
。Try using
base.AsQueryable()
instead ofthis.AsQueryable()
.