重點講 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 options)
: base(options)
{
}
public virtual DbSet Books { get; set; }
public virtual DbSet 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(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(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();
}
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 { 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 的。至少效能擺在那裡!
下麵取用官方的圖片,展示它們在功能上的比較:
朋友會在“發現-看一看”看到你“在看”的內容