您的位置:首页 > 数据库

Entity Framework code first 手动修改数据库的问题

2015-11-16 15:21 639 查看

1. 手动给表格添加字段或者新增一个表格会不会对DBContext产生影响呢?

不会产生影响,如果我们不想code中的model不和数据库中增加的保持一致,可以不添加对应的字段和model,但是如果我们需要保持一致,如何做呢

步骤如下:

a. 将Model手动改成与数据库一致

b. 在执行DbContext的实例化前加一句 Database.SetInitializer<BloggingContext>(null); 

c. 如果以后你需要在添加model ,则如果你把之前你手动改动与数据库同步的部分注释掉,然后再利用add-migration addmodel ;update-database来更新仍然是可以用的

下面的例子展示了如何做:

手动在数据更改之前:

1     public class Blog
2     {
3         public int BlogId { get; set; }
4         public string Name { get; set; }
5
6         public string Url { get; set; }
7         public virtual List<Post> Posts { get; set; }
8     }
9
10     public class User
11     {
12         [Key]
13         public int UserId { get; set; }
14         public string Username { get; set; }
15         public string DisplayName { get; set; }
16         //public int? age { get; set; }
17         //public string interest { get; set; }
18     }
19
20     public class School
21     {
22         public int SchoolId { get; set; }
23
24         public string SchoolName { get; set; }
25
26         public int SchoolLevel { get; set; }
27     }
28
29     public class Post
30     {
31         public int PostId { get; set; }
32         public string Title { get; set; }
33         public string Content { get; set; }
34
35         public int BlogId { get; set; }
36         public virtual Blog Blog { get; set; }
37     }
38
39     public class Tutorial
40     {
41         [Key]
42         public int Id { get; set; }
43
44         public int Name { get; set; }
45     }
46
47     public class BloggingContext : DbContext
48     {
49         public DbSet<Blog> Blogs { get; set; }
50         public DbSet<Post> Posts { get; set; }
51
52         public DbSet<User> Users { get; set; }
53
54          public DbSet<Tutorial> Tutorials { get; set; }
55         //public DbSet<School> Schools { get; set; }
56
57         pr

数据库中的表:



手动添加了表Schools并且更改了Users表中的字段



自己手动更改Model并保持与数据库同步

1     public class Blog
2     {
3         public int BlogId { get; set; }
4         public string Name { get; set; }
5
6         public string Url { get; set; }
7         public virtual List<Post> Posts { get; set; }
8     }
9
10     public class User
11     {
12         [Key]
13         public int UserId { get; set; }
14         public string Username { get; set; }
15         public string DisplayName { get; set; }
16         public int? age { get; set; }
17         public string interest { get; set; }
18     }
19
20     public class School
21     {
22         public int SchoolId { get; set; }
23
24         public string SchoolName { get; set; }
25
26         public int SchoolLevel { get; set; }
27     }
28
29     public class Post
30     {
31         public int PostId { get; set; }
32         public string Title { get; set; }
33         public string Content { get; set; }
34
35         public int BlogId { get; set; }
36         public virtual Blog Blog { get; set; }
37     }
38
39     public class Tutorial
40     {
41         [Key]
42         public int Id { get; set; }
43
44         public int Name { get; set; }
45     }
46
47     public class BloggingContext : DbContext
48     {
49         public DbSet<Blog> Blogs { get; set; }
50         public DbSet<Post> Posts { get; set; }
51
52         public DbSet<User> Users { get; set; }
53
54         public DbSet<Tutorial> Tutorials { get; set; }
55         public DbSet<School> Schools { get; set; }
56
57         protected override void OnModelCreating(DbModelBuilder modelBuilder)
58         {
59             modelBuilder.Entity<User>().Property(u => u.DisplayName).HasColumnName("display_name");
60             modelBuilder.Entity<User>().Property(u => u.Username).HasColumnName("user_name");

如果你调用add-migration and update-database 会提示 There is already an object named 'Schools' in the database.

所以你去访问数据库时会出现错误:

using (var db = new BloggingContext())
{
//var query2 = from b in db.Schools
//	     orderby b.SchoolName
//	     select b;
//var schoolList = query2.ToList();
var query1 = from b in db.Users
orderby b.Username
select b;
var userList = query1.ToList();
// Create and save a new Blog
Console.Write("Enter a name for a new Blog: ");
var name = Console.ReadLine();
var user = new User { UserId = 0, Username = name };
db.Users.Add(user);
db.SaveChanges();
//var blog = new Blog { Name = name };
//db.Blogs.Add(blog);
//db.SaveChanges();
// Display all Blogs from the database
var query = from b in db.Blogs
orderby b.Name
select b;
Console.WriteLine("All blogs in the database:");
foreach (var item in query)
{
Console.WriteLine(item.Name);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}

会产生异常:

An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll

Additional information: The model backing the 'BloggingContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

如果在using (var db = new BloggingContext())前加上Database.SetInitializer<BloggingContext>(null);就不会报错

但是如果以后想添加Model的话,怎么做呢,我们可以将之前你添加与手动添加School表和修改user表的一些信息注释掉,migration文件也删除,然后你在添加model再去执行数据迁移就不会出问题,迁移好了后,你在重新反注释即可。

2. 数据库连接字符串的更改

在 Code First 模式下按约定使用连接

如果您还没有在应用程序中进行任何其他配置,则对 DbContext 调用无参数构造函数将会导致 DbContext 使用按约定创建的数据库连接在 Code First 模式下运行。例如:

1 namespace Demo.EF
2 {
3     public class BloggingContext : DbContext
4     {
5         public BloggingContext()
6         // C# will call base class parameterless constructor by default
7         {
8         }
9     }
10 }


在此示例中,DbContext 使用派生上下文类 Demo.EF.BloggingContext 的命名空间限定名称作为数据库名称,并使用 SQL Express 或 LocalDb 为此数据库创建连接字符串。如果同时安装了这两个数据库,将使用 SQL Express。

默认情况下,Visual Studio 2010 包含 SQL Express,Visual Studio 2012 包含 LocalDb。安装期间,EntityFramework NuGet 包会检查哪个数据库服务器可用。随后 NuGet 包将设置按约定创建连接时 Code First 所使用的默认数据库服务器,以此更新配置文件。如果 SQL Express 正在运行,将使用它。如果 SQL Express 不可用,则 LocalDb 将注册为默认数据库。如果配置文件已包含默认连接工厂设置,则不会更改该文件。

在 Code First 模式下按约定和指定数据库名称使用连接

如果您尚未在应用程序中进行任何其他配置,在通过要使用的数据库名称对 DbContext 调用字符串构造函数时,将会导致 DbContext 使用按约定创建的与该名称数据库的连接在 Code First 模式下运行。例如:

public class BloggingContext : DbContext
{
public BloggingContext()
: base("BloggingDatabase")
{
}
}


在此示例中,DbContext 使用“BloggingDatabase”作为数据库名称,并使用 SQL Express(随 Visual Studio 2010 安装)或 LocalDb(随 Visual Studio 2012 安装)为此数据库创建连接字符串。如果同时安装了这两个数据库,将使用 SQL Express。

在 Code First 模式下使用 app.config/web.config 文件中的连接字符串

可以选择将连接字符串放入 app.config 或 web.config 文件中。例如:

<configuration>
<connectionStrings>
<add name="BloggingCompactDatabase"
providerName="System.Data.SqlServerCe.4.0"
connectionString="Data Source=Blogging.sdf"/>
</connectionStrings>
</configuration>


这是一种指示 DbContext 使用数据库服务器而非 SQL Express 或 LocalDb 的简单方法 — 上例指定了 SQL Server Compact Edition 数据库。

如果连接字符串的名称与上下文的名称(带或不带命名空间限定)相同,则使用无参数构造函数时 DbContext 会找到该连接字符串。如果连接字符串名称与上下文名称不同,则可通过将连接字符串名称传递给 DbContext 构造函数,指示 DbContext 在 Code First 模式下使用此连接。例如:

1 public class BloggingContext : DbContext
2 {
3     public BloggingContext()
4         : base("BloggingCompactDatabase")
5     {
6     }
7 }


或者,也可以对传递给 DbContext 构造函数的字符串使用 “name=<连接字符串名称>”格式。例如:

1 public class BloggingContext : DbContext
2 {
3     public BloggingContext()
4         : base("name=BloggingCompactDatabase")
5     {
6     }
7 }


使用此形式可以明确要求在配置文件中查找连接字符串。如果未找到具有给定名称的连接字符串,则将引发异常。

Database/Model First 使用 app.config/web.config 文件中的连接字符串

使用 EF 设计器创建的模型不同于 Code First,因为该模型事先已存在,而不是在应用程序运行时从代码生成的。该模型通常在项目中以 EDMX 文件形式存在。

Designer 会将 EF 连接字符串添加到 app.config 或 web.config 文件中。此连接字符串十分特殊,因为它说明了如何在 EDMX 文件中查找信息。例如:

1 <configuration>
2   <connectionStrings>
3     <add name="Northwind_Entities"
4          connectionString="metadata=res://*/Northwind.csdl|
5                                     res://*/Northwind.ssdl|
6                                     res://*/Northwind.msl;
7                            provider=System.Data.SqlClient;
8                            provider connection string=
9                                "Data Source=.\sqlexpress;
10                                      Initial Catalog=Northwind;
11                                      Integrated Security=True;
12                                      MultipleActiveResultSets=True""
13          providerName="System.Data.EntityClient"/>
14   </connectionStrings>
15 </configuration>


EF 设计器还将生成一些代码,指示 DbContext 通过将连接字符串名称传递给 DbContext 构造函数来使用此连接。例如:

1 public class NorthwindContext : DbContext
2 {
3     public NorthwindContext()
4         : base("name=Northwind_Entities")
5     {
6     }
7 }


由于连接字符串是包含待用模型详细信息的 EF 连接字符串,因此 EF DbContext 十分清楚要加载现有模型(而不是使用 Code First 从代码计算模型)。

其他 DbContext 构造函数选项

DbContext 类包含支持其他一些更高级方案的其他构造函数和使用模式。其中一些选项有:

可以使用 DbModelBuilder 类构建 Code First 模型,而不实例化 DbContext 实例。这样会生成 DbModel 对象。随后,在准备好创建 DbContext 实例时,可以将此 DbModel 对象传递给某一 DbContext 构造函数。
可以将完整连接字符串传递给 DbContext,而不仅仅传递数据库或连接字符串名称。此连接字符串默认用于 System.Data.SqlClient 提供程序;可以通过在 context.Database.DefaultConnectionFactory 上设置不同的 IConnectionFactory 实现来更改此行为。
可以通过将现有 DbConnection 对象传递给 DbContext 构造函数来使用该对象。如果连接对象是 EntityConnection 的实例,则将使用连接中指定的模型,而不使用 Code First 计算模型。如果该对象是其他某一类型(例如 SqlConnection)的实例,则上下文将在 Code First 模式下使用该对象。
可以通过将现有 ObjectContext 传递给 DbContext 构造函数,创建包装现有上下文的 DbContext。对于使用 ObjectContext 但希望在其中一部分利用 DbContext 的现有应用程序,这一点十分有用。

SQL 使用的连接字符串:

1 <connectionStrings>
2 <!--<add name="eRebateContext" connectionString="Database=eRebateTest;Server=10.40.15.16;uid=sa;pwd=a8@accnmis;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/>
3 <add name="NotesConnection" connectionString="server=10.40.15.16;database=Dealer;uid=sa;pwd=a8@accnmis;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/>-->
4 <add name="eRebateContext" connectionString="Database=eRebate;Server=V-BLCHEN-02;Trusted_connection=Yes;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
5 <add name="NotesConnection" connectionString="Database=Dealer;Server=V-BLCHEN-02;Trusted_connection=Yes;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
6 <!--<add name="eRebateContext" connectionString="Database=eRebate;Server=10.40.15.81;user=sa;password=mis" providerName="System.Data.SqlClient"/>
7 <add name="NotesConnection" connectionString="Database=Dealer;Server=10.40.15.81;user=sa;password=mis" providerName="System.Data.SqlClient"/>-->
8 </connectionStrings>

Mysql 使用的连接字符串 ( install Mysql.data.entity )

1   <connectionStrings>
2     <add name="JdCloudDbContext" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;database=jd_cloud_data;UID=root;password=root;"/>
3   </connectionStrings>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: