传统上,我总是手动编写 sql 脚本,因此它们干净整洁(我不喜欢生成的脚本),并且逐个发布,我提供了一个全新的安装脚本和一个来自先前版本的迁移脚本,用于创建新的表、更改现有表等。这都是相当标准的。
我确实没有太多时间首先尝试 EF 4 代码,但如果它在生产环境中确实可行,我非常有兴趣使用它。
假设您有一种代码优先方法,如果数据库不存在,将自动创建数据库。如果您发布了具有架构/模型更改的软件新版本,会发生什么情况。 EF 是否足够智能,可以更新数据库架构以匹配更新后的 EF 模型?
场景
- 客户端在其服务器上安装 asp.net MVC 网站。首次运行时,会创建一个新的数据库
- 客户端使用网站一段时间,数据库中会填充一些数据
- 同时发布新版本的网站,并且 EF 模型已更改
- 客户端下载新版本、部署网站并指向现有数据库
代码优先仅对初始部署有用,还是足够聪明,可以将现有数据库版本更新为这样的版本?
Traditionally I have always written my sql scripts by hand so they are nice and clean (I'm not a fan of the generated ones) and release to release, I provide a fresh install script and a migration script from the previous version that creates new tables, alters existing tables etc. This is all pretty standard.
I haven't really had much time to play around with EF 4 code first but am quite interested to use it if it is actually viable in a production environment.
Say you have a code first approach where a database will automatically be created if one does not exist. What happens if you release a new version of the software which has schema/model changes. Is EF smart enough to update the database schema to match the updated EF model?
Scenario
- Client installs asp.net MVC website on their server. Upon first run, a fresh database is created
- Client uses website for a while and the database gets populated with some data
- Meanwhile a new version of the website is released and the EF model has changed
- Client downloads new version, deploys website and points to existing database
Is code first only useful for initial deployment, or is it smart enough to update an existing database release to release like this?
发布评论
评论(5)
从 EF CTP4 开始,每次更改对象模型时都会删除并重新创建数据库(这不是默认约定,您必须通过设置数据库初始化程序策略显式告诉 EF Code-First 执行此操作)。
话虽这么说,EF 团队正在积极致力于 数据库演进(又名迁移)解决方案完全满足您的场景:将数据库架构演变成您的对象的解决方案模型随着时间的推移而变化,这本质上是试图改变数据库以使其与模型重新同步,而不是重新创建它。
根据 EF 团队的说法,此功能将作为 EF 下一版本的一部分提供,该版本预计将于 2011 年第一季度发布。
As of EF CTP4, your database will be dropped and recreated every time you change your object model (this is not the default convention and you have to explicitly tell EF Code-First to do so by setting a Database Initializer Strategy).
That being said, EF team are actively working on a Database Evolution (aka Migrations) Solution that exactly addresses your scenario: A solution that will evolve the database schema as your object model changes over time which essentially tries to alter the database to be back in sync with your model instead of recreating it.
As per EF team, this feature will be available as part of EF next version that is on track to be released on the 1st quarter of 2011.
创建数据库的能力只是 Code First 的一个功能 - 而且是一个可选功能。您根本不必使用此功能。事实上,Scott Gu 有一篇完整的博客文章致力于使用 Code First 使用现有数据库。
在数据库迁移发布之前,您必须提出另一个策略,该策略将只是像传统上那样管理您的 ALTER TABLE 脚本。因此,当您部署新版本时,您可以运行 ALTER 脚本并部署包含模型更改的代码。
话虽如此,您在 Code First 中可以获得更多选项,而不仅仅是每次简单地删除并重新创建数据库(这只是一个选项)。您还可以将初始化程序设置为仅在模型更改时重新创建数据库。您还可以将初始化程序设置为根本不运行(在您手动管理对数据库的更改的情况下)。 这篇文章将为您提供有关 EF 数据库初始值设定项的更多信息。
The ability to create a database is just one feature of Code First - and it's an optional feature. You don't have to use this feature at all. In fact, Scott Gu has an entire blog post dedicated to using Code First with an existing database.
Until the Database Migrations are released, you have to come up with another strategy and that strategy will simply be managing your ALTER TABLE scripts as you traditionally would have. So when you deploy a new version, you run your ALTER script and deploy the code that contains the changes to the model.
Having said all that, you get more options in Code First than simply dropping and recreating your database every time (that is just one option). You can also set the initializer to only recreated the database if the model changes. You can also set the initializer to never run at all (in the case where you're manually managing changes to the database). This post will give you more information on EF database initializers.
我正在研究数据库上下文初始化程序,如果模型和数据库架构不同步,它将通知网站管理员。这对于喜欢完全控制代码优先模型和数据库模式的开发人员来说非常有用。看看:
https://github.com/rialib/efextensions
I am working on database context initializer which will notify webmaster if model and db schema are out of sync. This can by useful for developers who prefer to have complete control both over code-first model and database schema. Check it out:
https://github.com/rialib/efextensions
几个月过去了,现在官方答案已经发布: IDatabaseInitializer。
这或多或少是您要寻找的内容:
取自此处: http://blog.cincura.net/231783-ultimate-efv4-ctp4-code-first-full-mapping-example-using-firebird/
现在你可以转换您的架构按照您习惯的方式进行。当然,您还可以编写一个更复杂的 DatabaseInitializer,它使用 C# 而不是 SQL,并执行更复杂的操作,例如在执行之前检查是否需要更改、在更改表时转换数据等。
另一个 StackOverflow 问题涉及修改表的一些细节:
实体框架代码优先流畅 API在 for 循环中设置字段属性
Months have passed and now the official answer has been released: IDatabaseInitializer.
Here's more or less what you're looking for:
Taken from here: http://blog.cincura.net/231783-ultimate-efv4-ctp4-code-first-full-mapping-example-using-firebird/
Now you can transform your schema the way you're used to. Of course, you could also write a more complex DatabaseInitializer that uses C# instead of SQL, and does more complex things like checking to see if an alter is necessary before performing it, transform data as it changes tables, etc.
Another StackOverflow question that deals with some of the details of modifying tables:
Entity Framework Code First fluent API setting field properties in a for loop
使用 EF 6,您可以重新设计您的数据库(代码优先),确保安装所有更新,有时您现有的数据库中可能有不同的架构,以便在您的上下文类中使用它们,
如果您不选择 EF 只选择 < code>dbo.yourtable 而不是像
FullDepot.secondtable
等表格Using EF 6 , u can re-engineer your database (code-first) make sure all updates are installed , sometimes u may have different schemas in your existing database to use them in your context class
if you don't EF only picks up
dbo.yourtable
and not tables likeFullDepot.secondtable
etc