EF中的来自数据库的EF设计器和来自数据库的CodeFirst的区别
2016-04-06 21:29
417 查看
本文主要介绍在ASP.NET MVC5和EntityFramework6.x环境下,在使用ADO.NET实体数据模型时,两个选项:来自数据库的EF设计器和来自数据库的CodeFirst的区别。
为了测试,在数据库中建立Test数据库,并建立User表:CREATE TABLE [dbo].[User] ( [Id] INT NOT NULL, [Name] NCHAR (10) NOT NULL, [Age] INT NOT NULL, [Gender] NCHAR (10) NOT NULL, PRIMARY KEY CLUSTERED ([Id] ASC) );
1.来自数据库的EF设计器
1.1 按照实体数据模型向导一步一步往下走
这里可以看到自动生成的连接字符串和连接名。
选择我们需要的实体
下面就是生成的模型,可以看到和数据库里的表结构是一一对应的:
我们还可以看到生成了好多的东西:
User.cs是向导根据数据库自动生成的User类,说明使用“来自数据库的EF设计器”时,不需要有实体类,这也就是DataFirst模式。
UserModel.Context.cs文件里包含的
TestEntities类是向导生成的数据上下文类,该类用于映射数据库,在控制器中对数据模型进行操作时都要先对其实例化,
name=TestEntities是连接数据库字符串的名称。
<connectionStrings> <add name="TestEntities" connectionString="metadata=res://*/UserModel.csdl|res://*/UserModel.ssdl|res://*/UserModel.msl;provider=System.Data.SqlClient;provider connection string="data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=|DataDirectory|\Test.mdf;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" /> </connectionStrings>
1.2 根据该模型创建包含视图的mvc5控制器(使用EF)
创建控制器后我们可以在控制器类中看到实例化数据上下文类的代码
private TestEntities db = new TestEntities();
2.来自数据库的CodeFirst
2.1 按照实体数据模型向导创建“来自数据库的CodeFirst模型(过程和第1部分一样)
生成的数据库连接字符串为:<add name="SecondModel" connectionString="data source=(LocalDB)\MSSQLLocalDB;attachdbfilename=|DataDirectory|\Test.mdf;integrated security=True;multipleactiveresultsets=True;application name=EntityFramework" providerName="System.Data.SqlClient" />
2.2 上一步完成后,在项目中生成了数据上下文类SecondModel.cs
和实体类User.cs
:
public partial class SecondModel : DbContext { public SecondModel() : base("name=SecondModel") { } public virtual DbSet<User> User { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<User>() .Property(e => e.Name) .IsFixedLength(); modelBuilder.Entity<User>() .Property(e => e.Gender) .IsFixedLength(); } }
[Table("User")] public partial class User { [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } [Required] [StringLength(10)] public string Name { get; set; } public int Age { get; set; } [Required] [StringLength(10)] public string Gender { get; set; } }
3.两种方式对比
3.1 连接数据库字符串对比:
第一种方式生成的字符串要比第二种多了一个metadata参数:metadata=res://*/UserModel.csdl|res://*/UserModel.ssdl|res://*/UserModel.msl;,这句话的意思是加载所有目录下的UserModel.csdl、ssdl、msl文件。
csdl:类定义实体模型,该文件配置的是将要生成的实体模型类
<EntityType Name="User"> <Key> <PropertyRef Name="Id" /> </Key> <Property Name="Id" Type="Int32" Nullable="false" /> <Property Name="Name" Type="String" MaxLength="10" FixedLength="true" Unicode="true" Nullable="false" /> <Property Name="Age" Type="Int32" Nullable="false" /> <Property Name="Gender" Type="String" MaxLength="10" FixedLength="true" Unicode="true" Nullable="false" /> </EntityType>
msl:定义实体模型和数据库间属性的映射
<Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs"> <EntityContainerMapping StorageEntityContainer="TestModelStoreContainer" CdmEntityContainer="TestEntities"> <EntitySetMapping Name="User"> <EntityTypeMapping TypeName="TestModel.User"> <MappingFragment StoreEntitySet="User"> <ScalarProperty Name="Id" ColumnName="Id" /> <ScalarProperty Name="Name" ColumnName="Name" /> <ScalarProperty Name="Age" ColumnName="Age" /> <ScalarProperty Name="Gender" ColumnName="Gender" /> </MappingFragment> </EntityTypeMapping> </EntitySetMapping> </EntityContainerMapping> </Mapping>
ssdl:根据数据库内部的属性生成的文件
<EntityType Name="User"> <Key> <PropertyRef Name="Id" /> </Key> <Property Name="Id" Type="int" Nullable="false" /> <Property Name="Name" Type="nchar" MaxLength="10" Nullable="false" /> <Property Name="Age" Type="int" Nullable="false" /> <Property Name="Gender" Type="nchar" MaxLength="10" Nullable="false" /> </EntityType>
这种数据库与实体之间的映射配置方便以后对数据库或实体类一方进行修改时,另一方的修改只需要修改映射文件就行了
3.2 生成文件的对比
第一种方式生成了一个edmx文件,其中包括了生成的实体类、数据上下文类、实体关系图、以及t4生成器第二种方式只生成了实体类和数据上下文类
对比两种方式生成的实体类:
public partial class User { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Gender { get; set; } }
[Table("User")] public partial class User { [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } [Required] [StringLength(10)] public string Name { get; set; } public int Age { get; set; } [Required] [StringLength(10)] public string Gender { get; set; } }
第二种生成的代码要详细一些,可以直接用作Model,而不用再修改或添加注解。
4.个人总结
如果数据库已经设计好,推荐使用第一种方式第二种方式如果后期修改了数据库,那么实体类重新生成比较方便,而第一种方式数据库修改后,只需更新一下模型,该过程学习成本高一些
各位大神帮我想想他们的优缺点吧
相关文章推荐
- Mysql中的MVCC
- mysql 存在更新 不存在插入
- 数据库的隔离级别介绍
- 6、Mysql的数据库的备份和还原
- node.js中如何使用mongodb数据库
- mysql账号增删改、数据导入导出命令举例
- MongoDB快速学习
- Oracle学习笔记(四)——上机练习一
- 5、Mysql的用户权限管理--查看,授权,回收
- hibrnate 两表 排序 sql
- [国嵌攻略][182][Sqlite嵌入式数据库移植]
- oracle PL/SQL小结
- Oracle数据库远程连接配置教程
- pl/sql 循环
- TimesTen与Oracle字符集查询
- SQL Server转换成MySQL
- mysql count(*),count(1),count(字段)的区别
- mysql删除同表重复记录保存id最小的记录
- 数据持久化,好高端~哎,数据库啊!!
- 10分钟学会理解和解决MySQL乱码问题