Repositories.EntityFramework 实现方式
今天记录一下自己的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 }
这里有个重要的方法就是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 }
数据迁移用了自动迁移,之前刚刚开始用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 }
Repository的代码在上一篇中已经贴出来了。实现了异步和同步的方法。
后续会将整个代码放到github上面