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

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         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");
61         }
62     }

数据库中的表:

手动添加了表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                                &quot;Data Source=.\sqlexpress;
10                                      Initial Catalog=Northwind;
11                                      Integrated Security=True;
12                                      MultipleActiveResultSets=True&quot;"
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;[email protected];MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/>
3 <add name="NotesConnection" connectionString="server=10.40.15.16;database=Dealer;uid=sa;[email protected];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>
时间: 2025-01-15 22:45:30

Entity Framework code first 手动修改数据库的问题的相关文章

Entity Framework Code First数据库连接

参考页面: http://www.yuanjiaocheng.net/entity/entitytypes.html http://www.yuanjiaocheng.net/entity/entity-relations.html http://www.yuanjiaocheng.net/entity/entity-lifecycle.html http://www.yuanjiaocheng.net/entity/code-first.html http://www.yuanjiaochen

Entity Framework Code First学习系列

Entity Framework Code First学习系列目录 Entity Framework Code First学习系列说明:开发环境为Visual Studio 2010 + Entity Framework 5.0+MS SQL Server 2012,在数据库方面Entity Framework Code First在Entity Framework 5.0仅支持MS SQL Server数据库.在接下来的随笔中,均使用项目名称为Portal的控制台应用程序为例.具体的系统学习目

Entity Framework Code First数据库迁移(DB Migration)

一.手动迁移 第1步.启用数据库迁移 打开程序包管理器控制台 工具->库程序包管理器->程序包管理器控制台 打开控制台后,在控制台管理窗口输入 Enable-Migrations 指令,铵下回车键,到这里已启用了数据库迁移,但还没执行,结果如下图: 第2步.运行数据库迁移 在控制台管理窗口输入 Add-Migration指令,来新增一条数据库迁移版本,输入时必须要带上一个版本名称 Add-Migration AddProductCategoryTypeName,如下图: 运行完成后会在解决方案

Entity Framework Code First 映射继承关系

转载 http://www.th7.cn/Program/net/201301/122153.shtml Code First如何处理类之间的继承关系.Entity Framework Code First有三种处理类之间继承关系的方法,我们将逐一介绍这三种处理方法. 1.Table Per Hierarchy(TPH): 只建立一个表,把基类和子类中的所有属性都映射为表中的列. 2.Table Per Type(TPT): 为基类和每个子类建立一个表,每个与子类对应的表中只包含子类特有的属性对

Entity Framework Code First关系映射约定

Entity Framework Code First关系映射约定 本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个不同表之间可以存在外键依赖关系,一个表自身也可以有自反关系(表中的一个字段引用主键,从而也是外键字段). Entity Framework Code First默认多重关系的一些约定规则: 一对多关系:两个类中分别包含一个引用和一个

Entity Framework Code First主外键关系映射约定

本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个不同表之间可以存在外键依赖关系,一个表自身也可以有自反关系(表中的一个字段引用主键,从而也是外键字段). Entity Framework Code First默认多重关系的一些约定规则: 一对多关系:两个类中分别包含一个引用和一个集合属性,也可以是一个类包含另一个类的引用属性,或一个类包含另一个类

Entity Framework Code First关系映射约定【l转发】

本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个不同表之间可以存在外键依赖关系,一个表自身也可以有自反关系(表中的一个字段引用主键,从而也是外键字段). Entity Framework Code First默认多重关系的一些约定规则: 一对多关系:两个类中分别包含一个引用和一个集合属性,也可以是一个类包含另一个类的引用属性,或一个类包含另一个类

Entity Framework Code First (三)Data Annotations

Entity Framework Code First 利用一种被称为约定(Conventions)优于配置(Configuration)的编程模式允许你使用自己的 domain classes 来表示 EF 所依赖的模型去执行查询.更改追踪.以及更新功能,这意味着你的 domain classes 必须遵循 EF 所使用的约定.然而,如果你的 domain classes 不能遵循 EF 所使用的约定,此时你就需要有能力去增加一些配置使得你的 classes 能够满足 EF 所需要的信息. C

Entity Framework Code First属性映射约定

参考页面: http://www.yuanjiaocheng.net/entity/code-first.html http://www.yuanjiaocheng.net/entity/mode-first.html http://www.yuanjiaocheng.net/entity/database-first.html http://www.yuanjiaocheng.net/entity/choose-development-approach.html http://www.yuan