EF中的来自数据库的EF设计器和来自数据库的CodeFirst的区别
来源:互联网 发布:千方百计软件 编辑:程序博客网 时间:2024/06/02 21:58
本文主要介绍在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.个人总结
- 如果数据库已经设计好,推荐使用第一种方式
- 第二种方式如果后期修改了数据库,那么实体类重新生成比较方便,而第一种方式数据库修改后,只需更新一下模型,该过程学习成本高一些
- 各位大神帮我想想他们的优缺点吧
0 0
- EF中的来自数据库的EF设计器和来自数据库的CodeFirst的区别
- EF CodeFirst关于数据库的一些基本操作
- EF codefirst 数据库迁移
- EF CodeFirst 数据库迁移
- EF CodeFirst 数据库初始化和迁移
- 写一个EF的CodeFirst的Demo
- 使用EF codefirst时遇到的几个问题
- 来自数据库的图片
- EF Core的安装、EF Core与数据库结合
- EF框架之CodeFirst创建数据库
- C# 之 EF CodeFirst创建MySQL数据库
- 利用EF来进行数据库的操作
- Entity Framework (EF)/Linq To entity/ ESQL(entity sql)区别 ADO.NET Entity Framework:来自微软官方的ORM框架
- 【EF】 EF的一些错误和解决办法
- EF CodeFirst 一对一关系、复杂类型的演变
- EF(EntityFramework) 的 CodeFirst 使用指南一(创建)
- EF(EntityFramework) 的 CodeFirst 使用指南二(基本使用)
- ef生成codefirst上下版本之间的迁移记录
- 闲说App的接口测试
- Python 练习册,每天一个小程序(0007)
- 将迷你音箱用作手机来电铃声放大器
- CentOS下添加sudo用户
- Oracle学习笔记(五)——Oracle表的管理
- EF中的来自数据库的EF设计器和来自数据库的CodeFirst的区别
- Android 操作数据库的框架——greenDAO的学习
- AlertDialog弹出对话框条件不成立不消失
- HDU2039
- LeetCode--sort-list
- Maven项目管理(一) IntelliJ Idea+Maven环境搭建与基于命令行的基本使用
- 对于UITextField 使用过程中遇到的各种问题的一个总结
- CodeForces 6C Alice, Bob and Chocolate
- Android的Widget的定时刷新