EF6 中的这个 Test DBSet 类可以适应 EF Core 吗?
Posted
技术标签:
【中文标题】EF6 中的这个 Test DBSet 类可以适应 EF Core 吗?【英文标题】:Can this TestDBSet class from EF 6 be adapted to work with EF Core? 【发布时间】:2019-07-12 00:52:59 【问题描述】:我正在尝试按照 EF 6 的本教程编写自己的测试替身来模拟测试实体框架核心:
https://docs.microsoft.com/en-us/ef/ef6/fundamentals/testing/writing-test-doubles
本教程停留在 TestDbSet 类上,该类应该提供 DbSet 的内存实现。但是,大多数成员与 EF Core 不兼容:
public class TestDbSet<TEntity> : DbSet<TEntity>, IQueryable, IEnumerable<TEntity>, IDbAsyncEnumerable<TEntity>
where TEntity : class
ObservableCollection<TEntity> _data;
IQueryable _query;
public TestDbSet()
_data = new ObservableCollection<TEntity>();
_query = _data.AsQueryable();
public override TEntity Add(TEntity item)
_data.Add(item);
return item;
public override TEntity Remove(TEntity item)
_data.Remove(item);
return item;
public override TEntity Attach(TEntity item)
_data.Add(item);
return item;
public override TEntity Create()
return Activator.CreateInstance<TEntity>();
public override TDerivedEntity Create<TDerivedEntity>()
return Activator.CreateInstance<TDerivedEntity>();
public override ObservableCollection<TEntity> Local
get return _data;
Type IQueryable.ElementType
get return _query.ElementType;
Expression IQueryable.Expression
get return _query.Expression;
IQueryProvider IQueryable.Provider
get return new TestDbAsyncQueryProvider<TEntity>(_query.Provider);
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
return _data.GetEnumerator();
IEnumerator<TEntity> IEnumerable<TEntity>.GetEnumerator()
return _data.GetEnumerator();
IDbAsyncEnumerator<TEntity> IDbAsyncEnumerable<TEntity>.GetAsyncEnumerator()
return new TestDbAsyncEnumerator<TEntity>(_data.GetEnumerator());
Add、Attach、Remove 和 Create 方法发生的错误对于所有四个方法都是一样的:
'TestDbSet
.Add(TEntity)':返回类型必须是 'EntityEntry ' 匹配被覆盖的成员 'DbSet .Add(TEntity)
谁能解释我是否可以将
【问题讨论】:
【参考方案1】:对于EntityEntry<TEntity>
,它表示跟踪的TEntity并检查源代码,它使用StateManager
将TEntity
转换为EntityEntry<TEntity>
。
您无法在 TestDbSet<TEntity>
中创建 StateManager
。
尝试检查以下代码是否适合您。
public class TestDbSet<TEntity> : DbSet<TEntity>, IQueryable, IEnumerable<TEntity>
where TEntity : class
ObservableCollection<TEntity> _data;
IQueryable _query;
public TestDbSet()
_data = new ObservableCollection<TEntity>();
_query = _data.AsQueryable();
public override EntityEntry<TEntity> Add(TEntity item)
_data.Add(item);
var entity = base.Attach(item);
return entity;
【讨论】:
感谢您的回复!我一直在尝试,但是测试在新行“var entity = base.Attach(item);”上中断出现错误“System.NotImplementedException:方法或操作未实现”。还有什么我可能错过的吗? @EliRush*** 您需要与退货实体合作吗?如果没有,请尝试return item as EntityEntry<T>;
或return null;
。【参考方案2】:
@Edward 您的解决方案运行良好,通过返回 null 教程现在至少在我的测试中与 EF 核心兼容,感谢您的提示。
TestContext 中的一些修改: - 使用 Microsoft.EntityFrameworkCore.Query.Internal; - 使用 Microsoft.EntityFrameworkCore.ChangeTracking; - 将 IDbAsyncEnumerable 和 IDbAsyncEnumerator 更改为 IAsyncEnumerable 和 IAsyncEnumerator - 添加、删除和附加方法:将返回类型从 TEntity 更改为 EntityEntry,并将每个方法中的最后一条语句更改为返回 null; - 其他一些方法会出现编译错误,删除即可。
【讨论】:
以上是关于EF6 中的这个 Test DBSet 类可以适应 EF Core 吗?的主要内容,如果未能解决你的问题,请参考以下文章
在 EF6 中是不是有可能有一个 DbSet<T> 仅存在于内存中,而其余的是真实表?