0

我想以编程方式为我的 EF 4.3 Code-First 数据库创建数据库创建脚本。数据库使用标准 DatabaseInitializer 机制创建得很好,但以下代码失败:

using(var dc = new MyContext())
{
    var objContext = (IObjectContextAdapter)dc;
    var script = objContext.ObjectContext.CreateDatabaseScript();
}

我得到的例外是:

不属于“timestamp”或“rowversion”类型的属性不支持存储生成的模式“Computed”。

我确实定义了一个“字符串”类型的计算列,但就像我说的,当通过内置的 DatabaseInitializer 创建时,数据库创建得很好。奇怪的是,使用此方法生成的架构实际上并没有创建计算列。

至于我为什么这样做,我有一个运行后创建的脚本,它删除了这个列并创建了一个真正的计算列。如果不指定在 EF 映射中计算的列,它将尝试在插入时为该列分配一个值,然后失败。

4

1 回答 1

1

暂时将数据库创建放在一边,设置“Computed”意味着 EF 不会尝试写入该列的值,而是会在每次查询该列时读取服务器(可能)是计算机的值。从 EF 的角度来看,任何数据类型都有一个计算列是有效的。

现在考虑从 EF 模型创建数据库。EF 不知道如何在数据库中创建计算列,实际上,根据列的类型,如果在某些数据库中没有触发器,甚至可能无法执行此操作。因此,在 EF4 中,决定在这些情况下抛出 CreateDatabaseScript。

但是,EF 4.3 及更高版本在面向 SQL Server 或 SQL Server Compact 时不再使用 CreateDatabaseScript。他们改为使用迁移管道。对于迁移管道,我们决定采用不同的方法,因为我们认为数据库创建总是抛出一个可能是完全有效的模型是错误的。特别是考虑到您可以在迁移中编写自己的 SQL,添加触发器或其他一些机制来使数据库创建有效的计算列。

因此,这就是为什么您会看到由 EF 4.3 创建的数据库(但没有做任何事情来计算列),但是当您尝试使用使用较旧的非迁移机制的 CreateDatabaseScript 时,您会看到相同的模型抛出。

解决此问题的方法是让 Migrations 创建脚本,而不是使用 CreateDatabaseScript。

于 2012-05-31T21:16:54.770 回答