Entity Framework是M$提供的一個ORM框架,它旨在為小型應用程序中數據層的快速開發提供便利。
nuget上185W多的下載量,說明.Net開發人員還是比較喜歡用EF的。但是EF在提供了便利性的同時也有許多缺點,以下就是我認為不應該應用EF的場景:
- 非SQL Server數據庫且無該數據庫的DataProvider
- 高性能要求。在進行一些復雜查詢的情況下,EF的性能表現不太好,而開發人員又無法控制SQL語句的生成
- 高安全性要求。有時候DB用戶僅僅具有EXEC的權限,而EF自動生成的類又不好用,還是需要自己來寫。
一些大中型企業應用往往具有以上幾種情況,此時就不適合使用EF了。
至於使用什么ORM,我個人認為NHibernate配置起來太麻煩,如果沒什么太特殊的要求,可以試一下ServiceStack.OrmLite能不能滿足需求。或者直接上ADO.Net
如果非要使用EF,建議使用EF最新的穩定發布版本(支持DbContext+Code first方式開發)。然后讀一下《Programming Entity Framework Code First》和《Programming Entity Framework DbContext》這兩本書(目前無中文版)。使用DbContext+Code first POCO+Repository模式,這樣既可以保證EF被Repository隔離,又可以保證可測試性,還能在需要更換ORM框架甚至是換成ADO.Net時少改一點代碼。
提供示例代碼下載(.Net 4+EF5)
示例代碼中有POCO和EF的Configurations,把EF相關的Configurations單獨拿出來保證了DB Model的純潔性。在這里大體摘一點東西給大家看看
首先是數據庫結構,我使用的是Code first,在第一次有實際的數據庫操作的時候會自動生成數據庫,生成后的數據庫結構如下圖:
數據庫的生成策略在EFContext類的靜態構造里面:
static EFContext() { // 指定數據庫生成策略為不存在時生成 // 還可以指定為: // DropCreateDatabaseAlways(總是刪除原有數據庫重建) // DropCreateDatabaseIfModelChanges(數據庫模型改變后刪除原有數據庫重建) Database.SetInitializer<EFContext>(new CreateDatabaseIfNotExists<EFContext>()); }
Album表的Configuration設置:
public class AlbumConfiguration : EntityTypeConfiguration<Album> { public AlbumConfiguration() { // 指定數據表名 ToTable("dbo.Album"); // 設定主鍵 HasKey(x => x.Id); // 設定數據列名及其它屬性 Property(x => x.Id).HasColumnName("Id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired(); Property(x => x.AlbumName).HasColumnName("AlbumName").IsRequired().HasMaxLength(50); Property(x => x.ArtistId).HasColumnName("ArtistId").IsRequired(); // 設置外鍵約束 HasRequired(foreignKeyTable => foreignKeyTable.Artist) .WithMany(primaryKeyTable => primaryKeyTable.Albums) .HasForeignKey(foreignKeyTable => foreignKeyTable.ArtistId); // 設置多對多關聯 HasMany(thisTable => thisTable.Tags) .WithMany(anotherForeignKeyTable => anotherForeignKeyTable.Albums) .Map(relationTable => relationTable .MapLeftKey("TagId") .MapRightKey("AlbumId") .ToTable("AlbumTags") ); } }
重寫EFContext類中的OnModelCreating函數,使用我們自定義的Configurations:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 設定數據庫生成配置 modelBuilder.Configurations.Add(new ArtistConfiguration()); modelBuilder.Configurations.Add(new AlbumConfiguration()); modelBuilder.Configurations.Add(new TagConfiguration()); }
Repository模式這里我就不多說了,具體看AbstractDbAccessor項目中的內容,EF的Repository實現在ConcreteDbAccessor項目EntityFramework目錄下的EFDbAccessor和Repository目錄