今天記錄一下自己的EntityFramework數據訪問層。這裡用通過泛型Repository的方式實現了數據的訪問。先上一張結構圖。 Configuration文件夾裡面的類是全部實體映射類。這些類全部繼承至EntityConfigurationBase類。 EntityConfiguration
今天記錄一下自己的EntityFramework數據訪問層。這裡用通過泛型Repository的方式實現了數據的訪問。先上一張結構圖。
Configuration文件夾裡面的類是全部實體映射類。這些類全部繼承至EntityConfigurationBase類。
EntityConfigurationBase又繼承至 EntityTypeConfiguration類,這是EntityFramework的實體映射基類
1 using System.Data.Entity.ModelConfiguration; 2 using System.Data.Entity.ModelConfiguration.Configuration; 3 4 using ZY.Core.Entities; 5 6 namespace ZY.Repositories.EntityFramework 7 { 8 /// <summary> 9 /// 數據實體映射配置基類 10 /// </summary> 11 /// <typeparam name="TEntity"></typeparam> 12 /// <typeparam name="TKey"></typeparam> 13 public abstract class EntityConfigurationBase<TEntity, TKey> : EntityTypeConfiguration<TEntity>, IEntityMapper 14 where TEntity : class 15 { 16 //映射實體添加到數據上下文 17 public void RegistorTo(ConfigurationRegistrar configurations) 18 { 19 configurations.Add(this); 20 } 21 } 22 }View Code
這裡有個重要的方法就是RegistorTo(ConfigurationRegistrar configurations) 這個方法是將當前實體添加到數據上下文。這樣不用在數據上下文寫每一個實體的映射,將實體與上下文解耦出來了。在OnModelCreating(DbModelBuilder modelBuilder) 方法裡面用到了反射,通過反射將所有實體映射關係添加到數據上下文中。這裡可以優化一下就是,反射的時候可以用緩存。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Data.Entity; 7 using System.Data.Entity.ModelConfiguration.Conventions; 8 using System.Reflection; 9 10 namespace ZY.Repositories.EntityFramework 11 { 12 public class BaseDbContext : DbContext 13 { 14 public BaseDbContext() 15 : base("Default") 16 { } 17 18 public BaseDbContext(string connectionString) 19 :base(connectionString) 20 { } 21 22 protected override void OnModelCreating(DbModelBuilder modelBuilder) 23 { 24 //關閉級聯刪除 25 modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 26 //獲取所有映射實體類 27 IEnumerable<IEntityMapper> entityMappers = GetEntityMappers().Select(type => Activator.CreateInstance(type) as IEntityMapper).ToList(); 28 29 foreach (IEntityMapper mapper in entityMappers) 30 { 31 mapper.RegistorTo(modelBuilder.Configurations); 32 } 33 } 34 35 /// <summary> 36 /// 通過反射 獲取所有實體映射對象 優化的做法是保存在緩存中 37 /// </summary> 38 /// <returns></returns> 39 private Type[] GetEntityMappers() 40 { 41 Type[] mapperTypes = Assembly.GetExecutingAssembly().GetTypes() 42 .Where(type => !String.IsNullOrEmpty(type.Namespace)) 43 .Where(type => type.BaseType != null && type.BaseType.IsGenericType && 44 type.BaseType.GetInterface(typeof(IEntityMapper).Name) == typeof(IEntityMapper)).ToArray(); 45 return mapperTypes; 46 } 47 } 48 }View Code
數據遷移用了自動遷移,之前剛剛開始用EF的時候沒有用自動遷移,遇到了很多坑,自從用了自動遷移,就沒有管過遷移的事情了。
1 using System.Data.Entity.Migrations; 2 3 4 namespace ZY.Repositories.EntityFramework.Migrations 5 { 6 /// <summary> 7 /// 自動遷移設置 8 /// </summary> 9 public class AutoMigrationsConfiguration : DbMigrationsConfiguration<BaseDbContext> 10 { 11 public AutoMigrationsConfiguration() 12 { 13 AutomaticMigrationsEnabled = true;//自動遷移 14 AutomaticMigrationDataLossAllowed = true;//允許數據丟失 15 } 16 } 17 }View Code
Repository的代碼在上一篇中已經貼出來了。實現了非同步和同步的方法。
後續會將整個代碼放到github上面