C# 从对象、实体框架自动创建数据库表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9873873/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Auto Create Database Tables from Objects, Entity Framework
提问by Pieces
I am trying to do this tutorial http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/getting-started-with-mvc3-part4-csbut instead of using the compact edition of SQL Server I am using a full install on my local machine. The way I read this tutorial is that the Entity Framework is suppose to create the tables from the objects I have defined. My problem is that I keep getting invalid object name dbo.movies, when I run the project. I finally got it to run by creating the table myself so I know the connection string and everything was correct.
我正在尝试做这个教程http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/getting-started-with-mvc3-part4-cs但不是使用精简版SQL Server 我在本地机器上使用完整安装。我阅读本教程的方式是 Entity Framework 假设从我定义的对象创建表。我的问题是,当我运行项目时,我不断收到无效的对象名称 dbo.movies。我终于通过自己创建表来运行它,所以我知道连接字符串并且一切都是正确的。
My question is, is it possible to generate tables from objects created in C# and if so how?
我的问题是,是否可以从在 C# 中创建的对象生成表,如果可以,如何?
采纳答案by Dismissile
is it possible to generate tables from objects created in C#?
是否可以从在 C# 中创建的对象生成表?
Yes it is possible. Did you happen to create the Database manually in Management Studio before running the Code? That could be your problem. With Code First, the default convention is to create the database if it does not exist already. If the database already exists (even without the tables) then it is going to just use the existing database (but it won't try and create the tables).
对的,这是可能的。您是否碰巧在运行代码之前在 Management Studio 中手动创建了数据库?那可能是你的问题。使用 Code First,如果数据库不存在,默认约定是创建数据库。如果数据库已经存在(即使没有表),那么它将只使用现有数据库(但它不会尝试创建表)。
You can either delete the database and try and run the code again to see if it will create it for you or put the following line in Global.asax:
您可以删除数据库并尝试再次运行代码以查看它是否会为您创建它或将以下行放入 Global.asax:
Database.SetInitializer(new DropCreateDatabaseAlways<YourDbContextHere>());
Once it has run then I would suggest changing that line to:
一旦运行,我建议将该行更改为:
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<YourDbContextHere>());
These namespaces are defined in System.Data.Entity
这些命名空间定义在 System.Data.Entity
The DbContextclass also exposes a Database property which defines the following useful methods:
所述DbContext类还公开它定义了以下有用的方法数据库属性:
Delete()
Create()
CreateIfNotExists()
So if you defined your class like so:
因此,如果您像这样定义类:
public class MyContext : DbContext {}
You can construct an instance like so:
您可以像这样构造一个实例:
MyContext db = new MyContext();
db.Database.Delete();
db.Database.Create();
回答by kyjan
If you create a Linq-to-Sql DataContext you can inject the structure directly into your Database whith:
如果您创建一个 Linq-to-Sql DataContext,您可以将结构直接注入到您的数据库中:
DbDataContext db = new DbDataContext(connectionString);
db.CreateDatabase();
回答by John
I don't know if this is kosher, but using code-first EF, when I use AddRange, EF will typically create all the tables I've defined. I wanted to keep the database because there are other tables I wanted to keep between application runs. I discovered that the tables would not be re-created after they were deleted if I did not also delete the table EF created called __MigrationHistory.
我不知道这是否是 kosher,但使用代码优先 EF,当我使用 AddRange 时,EF 通常会创建我定义的所有表。我想保留数据库,因为我想在应用程序运行之间保留其他表。我发现如果我没有同时删除 EF 创建的名为 __MigrationHistory 的表,这些表将不会在删除后重新创建。
Once I deleted this table, then EF would re-create the tables without having to re-create the database.
一旦我删除了这个表,EF 就会重新创建这些表,而不必重新创建数据库。
This may not be an advisable approach in production, but for my development needs this resolved my issue. Maybe it will help someone else.
这在生产中可能不是一种可取的方法,但对于我的开发需求,这解决了我的问题。也许它会帮助别人。
回答by Slava Utesinov
You can use FenixRepolibrary(also available as nuget package) to create particular table, that is a part of you Context. First of all, you should call one time, at startup staticInitializemethod, where first argument is a factory method, which returns instance of your Contextand the second one is an instance of Configurationclass. It will prepare SQL scripts for all of your tables, registered at your Context. At case of ASP.NET MVC it is a good decision to paste this code into Global.asax:
您可以使用FenixRepo库(也可用作nuget 包)来创建特定的表,这是您的一部分Context。首先,您应该在启动staticInitialize方法中调用一次,其中第一个参数是工厂方法,它返回 yourContext的实例,第二个参数是Configurationclass. 它将为您的所有表准备 SQL 脚本,在您的Context. 在 ASP.NET MVC 的情况下,将此代码粘贴到 Global.asax 中是一个很好的决定:
FenixRepositoryScriptExtractor.Initialize(() => new Context(), new Configuration());
Then you can create table of desired type MyTablethis simple way:
然后您可以通过MyTable这种简单的方式创建所需类型的表:
var repo = new FenixRepositoryCreateTable<MyTable>();
//or repo = new FenixRepository<MyTable>();
repo.CreateTable();
Also, if your table spread between several migrations and they have nothing stuff corresponded to other tables, you can specify these migrations(i.e. names of classes from Migrations folder) via FenixAttribute, and exactly they will be used as source of SQL scripts, which will be used for table creation:
此外,如果您的表分布在多个迁移之间并且它们没有与其他表对应的任何内容,您可以通过 指定这些迁移(即来自 Migrations 文件夹的类的名称)FenixAttribute,并且它们将被用作 SQL 脚本的源用于表创建:
[Fenix(nameof(Initial), nameof(MyTableFirstMigration), nameof(MyTableSecondMigration))]
public class MyTable
{
//some stuff
}
Without this attribute, library will use defaultscripts. It is always better to specify migrations, because otherwise it is not guaranteed that all indexes will be created and also into your migrations you can include some custom code, that will not be executed at case of defaultsolution.
如果没有此属性,库将使用默认脚本。指定迁移总是更好,因为否则不能保证所有索引都将被创建,并且您可以在迁移中包含一些自定义代码,这些代码不会在默认解决方案的情况下执行。
Library is compatible and tested with EF 6.1.3 at case of MS SQL.
在 MS SQL 的情况下,库与 EF 6.1.3 兼容并经过测试。
回答by Ronnie
ModelContext.Database.EnsureCreated();

