0

我正在使用实体框架,试图测试命中它的代码。所有代码都运行良好,但我在测试时遇到了问题。当我在测试时运行此代码时:

_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 生成一个测试数据库,这样我就可以创建适当的集成测试。提前致谢。

4

1 回答 1

2

如果您使用的是 EDMX,则不能使用数据库初始化(或 onmodelcreating)。这些功能是 Code First 特有的。

所以这里真的没有答案,因为您无法从 EDMX 生成测试数据库。

您可以遵循一些模式来动态创建测试数据库。从我在 2009 年写的一篇博文中粘贴 (http://thedatafarm.com/blog/data-access/unit-testing-in-ef-v1-the-database-conundrum/)

  • 复制/粘贴数据库:使用小型 SQL Server Express 数据库作为测试数据库。在特定测试过程中,将 db 文件复制/粘贴到特定位置,然后打开与它的连接。在测试结束时,吹掉文件。

  • 事务:在每个数据库访问测试中,将代码包装在 System.Transaction.TransactionScope 中。在测试结束时,不要完成事务,数据库将回滚。

  • 数据库脚本:另一个客户正在使用一个小型数据库,他会在每次测试开始时即时生成该数据库,然后在结束时删除数据库。

因此,在您的模型中定义密钥的位置(正如我在推特上建议的那样)。在设计器中,右键单击属于该键的每个实体属性,并确保在上下文菜单上单击“实体键”。然后,EF 将使用这些属性的组合作为它的复合实体键。

希望能帮助到你。

于 2013-01-15T21:43:40.920 回答