gpt4 book ai didi

c# - 模拟 IDbSet GetEnumerator 时 LINQ 失败

转载 作者:行者123 更新时间:2023-12-02 04:32:37 26 4
gpt4 key购买 nike

我正在尝试模拟 System.Data.Entity.IDbSet 以使其返回一些数据(在本例中只是一个空集合):

var mock = new Mock<IDbSet<Setting>>();
mock.Setup(x => x.GetEnumerator()).Returns(Enumerable.Empty<Setting>().GetEnumerator());
var myEnumerator = mock.Object.GetEnumerator();
var count = mock.Object.Count();

这里 myEnumerator 将有一个非空值,正如预期的那样,但是 mock.Object.Count() 将抛出一个 ArgumentNullException

System.ArgumentNullException : Value cannot be null.
Parameter name: arguments
at System.Linq.Expressions.Expression.RequiresCanRead(Expression expression, String paramName)
at System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi)
at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ref ReadOnlyCollection`1 arguments)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
at System.Linq.Queryable.Count(IQueryable`1 source)

如果我用 IEnumerable 替换 IDbSet,它会按预期工作(计数为零)。为什么 IDbSet 没有像我预期的那样被模拟?

编辑

看起来 LINQ 尝试使用 IQueryable 接口(interface),因为它有效:

var mock = new Mock<IDbSet<Setting>>();
var myQueryable = Enumerable.Empty<Setting>().AsQueryable();
mock.Setup(m => m.Provider).Returns(myQueryable.Provider);
mock.Setup(m => m.Expression).Returns(myQueryable.Expression);
mock.Setup(m => m.GetEnumerator()).Returns(myQueryable.GetEnumerator());
var count = mock.Object.Count();

最佳答案

事实证明,LINQ 具有 IQueryable 的显式实现:

    public static int Count<TSource>(this IQueryable<TSource> source) { 
if (source == null)
throw Error.ArgumentNull("source");
return source.Provider.Execute<int>(
Expression.Call(
null,
((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
new Expression[] { source.Expression }
));
}

实际上这很有意义,LINQ 表达式如何将表达式转换为 Entity Framework 查询。

所以我还必须模拟提供者和表达式:

var mock = new Mock<IDbSet<Setting>>();
var myQueryable = Enumerable.Empty<Setting>().AsQueryable();
mock.Setup(m => m.Provider).Returns(myQueryable.Provider);
mock.Setup(m => m.Expression).Returns(myQueryable.Expression);
mock.Setup(m => m.GetEnumerator()).Returns(myQueryable.GetEnumerator());
var count = mock.Object.Count();

关于c# - 模拟 IDbSet GetEnumerator 时 LINQ 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22706195/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com