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 }
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上面

posted on 2016-03-17 21:01  平飞  阅读(569)  评论(0编辑  收藏  举报