我正在使用Entity Framework,尝试测试能够实现它的代码。所有代码运行正常,但我的测试有问题。当我在测试时运行此代码时:
_entities = new Mock<MyEntities>();
Database.SetInitializer(new DropCreateDatabaseAlways<MyEntities>());
_entities.Object.Database.Initialize(true);
我得到“EntityType没有键定义”错误。之前我得到的是因为有些表不符合命名id列“ID”或“[Table Name] ID”的惯例。清理完之后,我仍然可以使用复合键将它们放到桌子上。就SQL而言,它们的定义是正确的。在EDMX设计器中,当我点击列时,他们说它们是键。那么如何正确地将它们定义为键呢?我在哪里放代码?
我试过这个,所有引用都专门针对Code First实现。无论如何我试过了。他们说要覆盖DbContext对象的OnModelCreating方法并将其添加到它:
modelBuilder.Entity<Widgets>().HasKey(widget => new { widget.A, widget.B });
所以我做了一个部分类并尝试覆盖它。它已经被覆盖了。所以我去了生成的部分类。这是实施:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
所以这不对。那我现在该怎么办?
我想在我的Web项目中基于EDMX生成测试数据库,以便我可以创建适当的集成测试。提前谢谢。
答案 0 :(得分:2)
如果您使用的是EDMX,则无法使用数据库初始化(或onmodelcreating)。这些功能特定于Code First。
因此,您无法从EDMX生成测试数据库。
您可以遵循一些模式来动态创建测试数据库。我在2009年写的博客文章中的Pastingi(http://thedatafarm.com/blog/data-access/unit-testing-in-ef-v1-the-database-conundrum/)
复制/粘贴数据库:使用小型SQL Server Express数据库作为 测试数据库。在特定测试过程中,复制/粘贴 db文件到特定位置,然后打开它的连接。 在测试结束时,吹走文件。
事务:在每个db访问测试中,将代码包装在一个 System.Transaction.TransactionScope。在测试结束时,不要 完成事务,db将回滚。
数据库脚本: 另一个客户端正在使用他将生成的小型数据库 每次测试开始时飞行,然后在最后删除数据库。
因此,在您的模型中,定义您的密钥的位置(正如我在推特上建议的那样)。在设计器中,右键单击属于该键的每个实体属性,并确保在上下文菜单中单击“实体键”。然后,EF将使用这些属性的组合作为它的复合实体密钥。
希望它有所帮助。