今天记录一下自己的EntityFramework数据访问层。这里用通过泛型Repository的方式实现了数据的访问。先上一张结构图。

Configuration文件夹里面的类是全部实体映射类。这些类全部继承至EntityConfigurationBase类。

EntityConfigurationBase又继承至 EntityTypeConfiguration类,这是EntityFramework的实体映射基类

 using System.Data.Entity.ModelConfiguration;
using System.Data.Entity.ModelConfiguration.Configuration; using ZY.Core.Entities; namespace ZY.Repositories.EntityFramework
{
/// <summary>
/// 数据实体映射配置基类
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TKey"></typeparam>
public abstract class EntityConfigurationBase<TEntity, TKey> : EntityTypeConfiguration<TEntity>, IEntityMapper
where TEntity : class
{
//映射实体添加到数据上下文
public void RegistorTo(ConfigurationRegistrar configurations)
{
configurations.Add(this);
}
}
}

这里有个重要的方法就是RegistorTo(ConfigurationRegistrar configurations) 这个方法是将当前实体添加到数据上下文。这样不用在数据上下文写每一个实体的映射,将实体与上下文解耦出来了。在OnModelCreating(DbModelBuilder modelBuilder) 方法里面用到了反射,通过反射将所有实体映射关系添加到数据上下文中。这里可以优化一下就是,反射的时候可以用缓存。

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Reflection; namespace ZY.Repositories.EntityFramework
{
public class BaseDbContext : DbContext
{
public BaseDbContext()
: base("Default")
{ } public BaseDbContext(string connectionString)
:base(connectionString)
{ } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//关闭级联删除
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
//获取所有映射实体类
IEnumerable<IEntityMapper> entityMappers = GetEntityMappers().Select(type => Activator.CreateInstance(type) as IEntityMapper).ToList(); foreach (IEntityMapper mapper in entityMappers)
{
mapper.RegistorTo(modelBuilder.Configurations);
}
} /// <summary>
/// 通过反射 获取所有实体映射对象 优化的做法是保存在缓存中
/// </summary>
/// <returns></returns>
private Type[] GetEntityMappers()
{
Type[] mapperTypes = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.BaseType != null && type.BaseType.IsGenericType &&
type.BaseType.GetInterface(typeof(IEntityMapper).Name) == typeof(IEntityMapper)).ToArray();
return mapperTypes;
}
}
}

数据迁移用了自动迁移,之前刚刚开始用EF的时候没有用自动迁移,遇到了很多坑,自从用了自动迁移,就没有管过迁移的事情了。

 using System.Data.Entity.Migrations;

 namespace ZY.Repositories.EntityFramework.Migrations
{
/// <summary>
/// 自动迁移设置
/// </summary>
public class AutoMigrationsConfiguration : DbMigrationsConfiguration<BaseDbContext>
{
public AutoMigrationsConfiguration()
{
AutomaticMigrationsEnabled = true;//自动迁移
AutomaticMigrationDataLossAllowed = true;//允许数据丢失
}
}
}

Repository的代码在上一篇中已经贴出来了。实现了异步和同步的方法。

后续会将整个代码放到github上面

Repositories.EntityFramework 实现方式的更多相关文章

  1. C#+EntityFramework编程方式详细之Code First 数据迁移

    在前几篇的C#+EntityFramework编程方式中介绍了C#+EntityFramework编程方式Code First ,Model First以及Dtatabase First 等编程方式, ...

  2. C#+EntityFramework编程方式详细之Model First

    Model First Model First模式即“模型优先”,这里的模型指的是“ADO.NET Entity Framework Data Model”,此时你的应用并没有设计相关数据库,在VS中 ...

  3. C#+EntityFramework编程方式详细之Code First

    Code First Code First模式即“代码优先”模式,是从EF4.1开始新建加入的功能.使用Code First模式进行EF开发时只需要编写对应的数据类,然后自动生成数据库. Code F ...

  4. C#+EntityFramework编程方式详细之Database First

    Database First “Database First”模式即“数据库优先”,其实Database First 与Model First 很类似,只不过一个是有数据可一个是创建数据库,具体的操作 ...

  5. [.NET领域驱动设计实战系列]专题二:结合领域驱动设计的面向服务架构来搭建网上书店

    一.前言 在前面专题一中,我已经介绍了我写这系列文章的初衷了.由于dax.net中的DDD框架和Byteart Retail案例并没有对其形成过程做一步步分析,而是把整个DDD的实现案例展现给我们,这 ...

  6. 我的“第一次”,就这样没了:DDD(领域驱动设计)理论结合实践

    写在前面 插一句:本人超爱落网-<平凡的世界>这一期,分享给大家. 阅读目录: 关于DDD 前期分析 框架搭建 代码实现 开源-发布 后记 第一次听你,清风吹送,田野短笛:第一次看你,半弯 ...

  7. 一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?

    写在前面 阅读目录: 问题根源是什么? <领域驱动设计-软件核心复杂性应对之道>分层概念 Repository(仓储)职责所在? Domain Model(领域模型)重新设计 Domain ...

  8. Apworks框架实战(六):使用基于Entity Framework的仓储基础结构

    在前面的章节中,我们已经设计了一个简单的领域模型,接下来我们希望能够实现领域模型的持久化及查询.在Apworks中,实现了面向Entity Framework.NHibernate以及MongoDB的 ...

  9. DDD 领域驱动设计-Value Object(值对象)如何使用 EF 进行正确映射

    写在前面 首先,这篇博文是用博客园新发布的 MarkDown编辑器 编写的,这也是我第一次使用,语法也不是很熟悉,但我觉得应该会很爽,博文后面再记录下用过的感受,这边就不多说. 阅读目录: 上一篇回顾 ...

随机推荐

  1. Android学习之路——简易版微信为例(三)

    最近好久没有更新博文,一则是因为公司最近比较忙,另外自己在Android学习过程和简易版微信的开发过程中碰到了一些绊脚石,所以最近一直在学习充电中.下面来列举一下自己所走过的弯路: (1)本来打算前端 ...

  2. FCLK PCLK HCLK

    一.对clock的基本认识 1 s3c2410的clock & power management模块包含三个部分:clock control.usb control.power control ...

  3. 洛谷P1238 走迷宫

    洛谷1238 走迷宫 题目描述 有一个m*n格的迷宫(表示有m行.n列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这m*n个数据和起始点.结束点(起始点和结束点都是用两个 ...

  4. BestCoder Round #81 (div.2)C String

    总体思路好想,就是在找K个不同字母的时候,卡时间. 看了大神代码,发现goto的!!!!998ms #include<cstdio> #include<cstring> #in ...

  5. redis命令之lrange

    LRANGE key start stop Related commands BLPOP BRPOP BRPOPLPUSH LINDEX LINSERT LLEN LPOP LPUSH LPUSHX ...

  6. 【Java基础】增强for循环要注意陷阱

    什么是增强for循环 增强for循环是一种简单模式的for循环,为了方便数组和集合的遍历而存在. int[] arr = new int[]{1, 2, 3, 4, 5, 6}; for (int a ...

  7. if

    语句快中的变量与函数的局部变量关系;

  8. java实现下载文件到本地

    代码如下: URL url = new URL("http://www.cnblogs.com/images/logo_small.gif"); URLConnection con ...

  9. Delphi- 内置数据库的使用例子BDE

    以前开发时经常使用一些大型的数据库,像这样小的数据库还是前段时间才看到.看看Delphi怎么使用内置的数据库, 先在BDE里拉两个数据库控件.DataBase和Table,然后再拉两个数据库控件Dat ...

  10. ASP.NET- Repeater 嵌套

    我们有时候需要查找出父菜单下面全部的子菜单,然后根据子菜单的ID查找出该类别下面的全部新闻. 通常往往只知道父级菜单的ID,但不知道父级菜单下面有多少个子菜单,也不知道子菜单的ID 所以我们往往需要根 ...