重点讲 Entity Framework Core !
(一)Entity Framework
它是适用于. NET 的对象关系映射程序 (ORM), 现在的 EF6 已经是久经沙场, 并经历重重磨难, 获得一致认可的数据访问技术(原来加 Title 也挺有意思的, 哈哈哈).
作为 ORM,EF6 降低了关系方面和面向对象的方面之间的阻抗不匹配, 使开发人员能够使用表示应用程序域的强类型 .NET 对象来编写应用程序, 该应用程序可与存储在关系数据库中的数据交互, 同时使开发人员无需再编写大部分的数据访问 "管道" 代码. 这是微软官方吹牛逼的原话, 但也很好理解.
那基于 EF6 可以实现很多 ORM 的热门的一些功能:
不依赖于任何 EF 类型的 POCO (Plain Old CLR Object) 实体类的映射
自动更改跟踪
标识解析和工作单元
预先, 延迟和显式加载
使用 LINQ(语言集成查询)转换强类型查询
丰富的映射功能, 可支持:
一对一, 一对多和多对多关系
继承(每个层次结构一张表, 每个类型一张表和每个具体类一张表)
复杂类型
存储过程
通过可视化设计器创建实体模型.
通过编写代码创建实体模型的 "Code First" 体验.
既可从现有数据库生成模型, 然后手动编辑, 也可从头开始创建模型, 然后用于生成新的数据库.
与 .NET Framework 应用程序模型 (包括 ASP.NET) 集成, 并通过数据绑定与 WPF 和 WinForms 集成.
基于 ADO.NET 的数据库连接和可用于连接到 SQL Server,Oracle,MySQL,SQLite,PostgreSQL,DB2 等的众多提供程序.
相信很多人都使用过 VS 中 EF 设计器, 我以前用得比较多, 主要就是在项目中创建的:
项目 ->添加新项...
选择数据左侧的菜单, 然后 ADO.NET 实体数据模型;
用生成的 Model 作为名称, 然后单击确定;
这将启动实体数据模型向导;
选择从数据库生成单击下一步;
选择连接到第一个部分中创建的数据库中, 直接用生成的 LibraryEntities 作为名称的连接字符串和单击下一步;
选择好实体框架 6.x , 下一步;
再单击表导入的所有表并单击完成旁边的复选框, 点击完成.
反向工程过程完成后, 新的模型就添加到了项目, 并直接打开了实体框架设计器
那么现在已经创建完了实体模型. 在创建的过程当中, 已经帮我们建好了数据类型, 生成了表的映射还有存储过程的映射, 这贼爽了, 点几下就搞定了, 接着就可以进行增删改查了(具体怎么做, 这里就不详解了).
EF 设计器中, 我们同样可以操作表, 更新表的字段, 再通过正向工程, 可以更新数据库中的表.
PS: 使用 Code First 生成的实体, 比 EF 设计器生成的要干净, 但是也失去了正向工程的功能.
(二)Entity Framework Core
它是轻量化, 可扩展, 开源和跨平台版的常用 Entity Framework 数据访问技术. 可用作对象关系映射程序 (ORM), 以便于 .NET 开发人员能够使用 .NET 对象来处理数据库, 这样就不必经常编写大部分数据访问代码了.
EF Core 则完全进行了重写, 包含许多 EF6 没有的新功能, 但还是缺少 EF6 中最高级的一些映射功能.
那如果要通过 VS 进行反向工程的话, 需要安装 PMC 工具, 而且这个工具是仅限于 VS 使用的. 当然也还有一些非常棒的代码生成工具, 比如 Code Smith.
使用 PMC 生成实体过程:
打开 VS 的程序包管理控制台
在程序包管理器控制台 (PMC) 工具中使用命令 Scaffold-DbContext 来进行反向工程.
当出入命名直接回车后, 会在项目的根目录下生成文件. 当然, 你也可以在 Scaffold-DbContext 命令中加入指定的生成路径等设置命令的.
这个跟用 EF 中用 Code First 生成文件是一个毛样的结果. 下图就是 Code First 生成的.
当然, 他们生成的代码还是有区别的. 我们来看看 Scaffold-DbContext 命令生成的三个文件的代码:
- 1,LibraryContext.cs
- public partial class LibraryContext : DbContext
- {
- public LibraryContext()
- {
- }
- public LibraryContext(DbContextOptions<LibraryContext> options)
- : base(options)
- {
- }
- public virtual DbSet<Books> Books { get; set; }
- public virtual DbSet<Categories> Categories { get; set; }
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- if (!optionsBuilder.IsConfigured)
- {
- optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=Library;integrated security=true");
- }
- }
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- modelBuilder.HasAnnotation("ProductVersion", "2.2.3-servicing-35854");
- modelBuilder.Entity<Books>(entity =>
- {
- entity.ToTable("books");
- entity.Property(e => e.Id)
- .HasColumnName("id")
- .ValueGeneratedNever();
- entity.Property(e => e.Author)
- .IsRequired()
- .HasColumnName("author")
- .HasMaxLength(50);
- entity.Property(e => e.Cateid).HasColumnName("cateid");
- entity.Property(e => e.Createtime)
- .HasColumnName("createtime")
- .HasColumnType("datetime");
- entity.Property(e => e.Isdel).HasColumnName("isdel");
- entity.Property(e => e.Name)
- .IsRequired()
- .HasColumnName("name")
- .HasMaxLength(50);
- entity.HasOne(d => d.Cate)
- .WithMany(p => p.Books)
- .HasForeignKey(d => d.Cateid)
- .OnDelete(DeleteBehavior.ClientSetNull)
- .HasConstraintName("FK_books_categories");
- });
- modelBuilder.Entity<Categories>(entity =>
- {
- entity.ToTable("categories");
- entity.Property(e => e.Id)
- .HasColumnName("id")
- .ValueGeneratedNever();
- entity.Property(e => e.Cascadeid)
- .IsRequired()
- .HasColumnName("cascadeid")
- .HasMaxLength(20);
- entity.Property(e => e.Createtime)
- .HasColumnName("createtime")
- .HasColumnType("datetime");
- entity.Property(e => e.Fid).HasColumnName("fid");
- entity.Property(e => e.Isdel).HasColumnName("isdel");
- entity.Property(e => e.Name)
- .IsRequired()
- .HasColumnName("name")
- .HasMaxLength(50);
- });
- }
- }
- 2,Categories.cs
- public partial class Categories
- {
- public Categories()
- {
- Books = new HashSet<Books>();
- }
- public int Id { get; set; }
- public int Fid { get; set; }
- public string Name { get; set; }
- public string Cascadeid { get; set; }
- public DateTime Createtime { get; set; }
- public bool Isdel { get; set; }
- public virtual ICollection<Books> Books { get; set; }
- }
- 3,Books.cs
- public partial class Books
- {
- public int Id { get; set; }
- public int Cateid { get; set; }
- public string Name { get; set; }
- public string Author { get; set; }
- public DateTime Createtime { get; set; }
- public bool Isdel { get; set; }
- public virtual Categories Cate { get; set; }
- }
通过上面可以看到, 它们已经生成好了映射. 但是, 如果要映射存储过程的话, EF Core 是不支持的.
(三)它们的区别
EF Core 提供了在 EF6 中不会实现的新功能(如备选键, 批量更新以及 LINQ 查询中的混合客户端 / 数据库评估. 但由于它是一个新代码库, 所以会缺少一些 EF6 中的功能. 这也是正常的, 但是它还在不断的完善!
EF Core 是更现代, 可扩展的轻量级实体框架版本, 与 EF6 的功能和优点非常相似. 如果功能与需求都匹配的话, 可以优先考虑使用 EF Core 的. 至少性能摆在那里!
下面引用官方的图片, 展示它们在功能上的比较:
来源: https://www.cnblogs.com/Vam8023/p/10778511.html