我目前正在使用扩展方法来将 DbSets 一般模拟为列表:
public static DbSet<T> AsDbSet<T>(this List<T> sourceList) where T : class
{
var queryable = sourceList.AsQueryable();
var mockDbSet = new Mock<DbSet<T>>();
mockDbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
mockDbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
mockDbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
mockDbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(queryable.GetEnumerator());
mockDbSet.Setup(x => x.Add(It.IsAny<T>())).Callback<T>(sourceList.Add);
mockDbSet.Setup(x => x.Remove(It.IsAny<T>())).Returns<T>(x => { if (sourceList.Remove(x)) return x; else return null; } );
return mockDbSet.Object;
}
但是,我无法找到模拟 Find 方法的方法,该方法根据表的主键进行搜索。我可以在每个表的特定级别执行此操作,因为我可以检查数据库,获取 PK,然后模拟该字段的 Find 方法。但这样我就不能使用通用方法了。
我想我也可以添加到 EF 自动生成的部分类中,以标记哪个字段是带有属性或其他内容的 PK。但是我们有 100 多个表,如果您依靠人们手动维护它,那么代码会变得更难以管理。
EF6 是否提供了查找主键的任何方法,还是只有在连接到数据库后才动态知道?
经过一段时间的思考后,我想我已经找到了当前可用的“最佳”解决方案。我只有一系列 if 语句,直接检查扩展方法中的类型。然后,我将其转换为设置查找行为所需的类型,并在完成后将其转换回通用类型。这只是伪通用的,但我想不出更好的东西。
if (typeof(T) == typeof(MyFirstSet))
{
mockDbSet.Setup(x => x.Find(It.IsAny<object[]>())).Returns<object[]>(x => (sourceList as List<MyFirstSet>).FirstOrDefault(y => y.MyFirstSetKey == (Guid)x[0]) as T);
}
else if (typeof(T) == typeof(MySecondSet))
{
mockDbSet.Setup(x => x.Find(It.IsAny<object[]>())).Returns<object[]>(x => (sourceList as List<MySecondSet>).FirstOrDefault(y => y.MySecondSetKey == (Guid)x[0]) as T);
}
...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)