我对实体进行了更改,运行了迁移并更新了数据库。 然后我重新进行了测试并且发出错误:
支持' EFDbContextProxy'自创建数据库以来,上下文已更改。考虑使用Code First Migrations来更新数据库
如果我运行该应用程序,我不会收到此错误。看来我的EFDbContextProxy(无论如何)正在使用数据结构的旧缓存。
有任何想法如何解决这个问题?
这是我在测试中准备db上下文的方法:
public class EFFieldViewerRepository_Setup
{
protected DateTime now;
protected Mock<EFDbContext> mockDbContext;
protected EFFieldViewerRepository fieldViewerRepository;
protected IDbSet<FieldViewer> fieldViewerDbSet;
public EFFieldViewerRepository_Setup()
{
this.now = DateTime.Now;
this.mockDbContext = new Mock<EFDbContext>() { CallBase = true };
this.fieldViewerRepository = new EFFieldViewerRepository( this.mockDbContext.Object );
...
}
这是我的堆栈跟踪:http://pastebin.com/kAUmhi3j
答案 0 :(得分:1)
我必须创建一个MockEFDbContext并扩展EFDbContext。在构造内部,我运行Database.SetInitializer<EFDbContext>(null)
:
public class MockEFDbContext : EFDbContext
{
public MockEFDbContext()
{
Database.SetInitializer<EFDbContext>(null);
}
}
然后我在我的测试中使用了这个新的MockEFDbContext
而不是正常的:{/ p>
this.mockDbContext = new Mock<MockEFDbContext>() { CallBase = true };
<强>来源:强>
- http://gaui.is/how-to-mock-the-datacontext-entity-framework/
- https://msdn.microsoft.com/en-us/library/gg679461(v=vs.113).aspx
答案 1 :(得分:0)
如果将Entity Framework配置为生成LocalDB数据库,则由Castle创建的Moq的DBContext代理类将依次创建一个LocalDB数据库,该数据库可能与最初创建数据库后添加的EF迁移不同步。我发现删除LocalDB数据库可以解决此问题,尽管可能有更好的解决方案,包括@ Jimmyt1988提供的答案。
我在一个Visual Studio测试项目中使用Moq运行单元测试,该项目也具有连接到目标数据库的集成测试。因此,我最终在我的app.config中有了一个这样的节点。
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="Oracle.ManagedDataAccess.Client" type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.122.18.3, Culture=neutral, PublicKeyToken=89b483f429c47342" />
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
我的Moq测试设置类似于@ Jimmyt1988的
private Mock<DbSet<OutgoingEntry>> _set;
private Mock<MyContext> _context;
private ModelService<OutgoingEntry, MyContext> _service;
[NUnit.Framework.SetUp]
public void Setup()
{
_set = new Mock<DbSet<OutgoingEntry>>();
_set.Reset();
_context = new Mock<MyContext>();
_context.Reset();
_context.Setup(m => m.OutgoingEntries).Returns(_set.Object);
_context.Setup(m => m.Set<OutgoingEntry>()).Returns(_set.Object);
_service = new OutgoingService(_context.Object);
}
在上面的示例中,_context.Object
是Castle.Proxies.MyContextProxy
的实例。这是在运行时生成的,以允许Moq覆盖“方法和属性”。但是,如果EF的配置如上所述,则代理类的生成仍将触发数据库初始化。最终将导致这样的数据库:
当我添加新迁移时,以上所有详细信息对我而言或多或少是透明的。不幸的是,这导致了原始问题中提到的确切错误。为了解决根本问题,我只是删除了Moq / Castle创建的LocalDB文件。这比听起来要棘手。我发现这些特定步骤适用于Windows 10。
SqlLocalDB.exe stop mssqllocaldb
。SqlLocalDB.exe delete mssqllocaldb
此命令将有效删除您拥有的所有LocalDB数据库。仅当您不关心LocalDB mssqllocaldb实例时才这样做。