在上一篇中,我列举了框架的整体结构,下面我们将一一说明:

首先需要说明的是TinyFrame.Data。

它主要用于处理数据库底层操作。包含EF CodeFirst,Repository,Unitofwork三个部分。

其中,DomainModel主要是用来存放实体类的:

   1:  namespace TinyFrame.Data.DomainModel
   2:  {
   3:      public class Book
   4:      {
   5:          public int ID { get; set; }
   6:          public string Name { get; set; }
   7:          public string Author { get; set; }
   8:          public string Publishment { get; set; }
   9:          public int BookTypeID { get; set; }
  10:          public int BookPlaceID { get; set; }
  11:   
  12:          public virtual BookType BookType { get; set; }
  13:          public virtual BookPlace BookPlace { get; set; }
  14:      }
  15:  }

然后,在DomainMapper中,则主要处理数据库字段属性和主外键映射:

   1:  using System.Data.Entity.ModelConfiguration;
   2:  using System.ComponentModel.DataAnnotations.Schema;
   3:  using TinyFrame.Data.DomainModel;
   4:   
   5:  namespace TinyFrame.Data.DomainMapper
   6:  {
   7:      public class BookMapper:EntityTypeConfiguration<Book>
   8:      {
   9:          public BookMapper()
  10:          {
  11:              this.ToTable("Book");
  12:   
  13:              this.HasKey(c => c.ID);
  14:              this.Property(c => c.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
  15:              this.Property(c => c.ID).IsRequired();
  16:   
  17:              this.Property(c => c.Name).HasMaxLength(255);
  18:              this.Property(c => c.Name).IsRequired();
  19:   
  20:              this.Property(c => c.Author).HasMaxLength(255);
  21:              this.Property(c => c.Author).IsOptional();
  22:   
  23:              this.Property(c => c.Publishment).HasMaxLength(255);
  24:              this.Property(c => c.Publishment).IsRequired();
  25:   
  26:              this.HasRequired(c => c.BookType).WithMany().HasForeignKey(s => s.BookTypeID).WillCascadeOnDelete(false);
  27:              this.HasRequired(c => c.BookPlace).WithMany().HasForeignKey(s => s.BookPlaceID).WillCascadeOnDelete(false);
  28:   
  29:          }
  30:      }
  31:  }

上面的代码中,ToTable方法适用于生成数据库新表;HasKey方法则指定主键;Property方法则用于设置字段属性;至于最后两句则主要用于设定主外键映射的,这里我们不做过多讲解。

最后在DataContext中,我们需要进行配置:

   1:  using System;
   2:  using System.Data.Entity;
   3:  using System.Data.Entity.Validation;
   4:  using TinyFrame.Data.DomainModel;
   5:  using TinyFrame.Data.DomainMapper;
   6:   
   7:  namespace TinyFrame.Data.DataContext
   8:  {
   9:      public class BookContext : DbContext, IDbContext
  10:      {
  11:          public BookContext()
  12:              : base("BookConnection")
  13:          {
  14:              Configuration.ProxyCreationEnabled = false;
  15:              Configuration.LazyLoadingEnabled = true;
  16:              Database.SetInitializer(new MigrateDatabaseToLatestVersion<BookContext, BookContextMConfig>());
  17:          }
  18:   
  19:          public DbSet<Book> Books { get; set; }
  20:          public DbSet<Student> Students { get; set; }
  21:          public DbSet<BookLend> BookLends { get; set; }
  22:          public DbSet<BookType> BookTypes { get; set; }
  23:          public DbSet<BookPlace> BookPlaces { get; set; }
  24:          public DbSet<Manager> Managers { get; set; }
  25:   
  26:          protected override void OnModelCreating(DbModelBuilder modelBuilder)
  27:          {
  28:              modelBuilder.Configurations.Add(new BookMapper());
  29:              modelBuilder.Configurations.Add(new BookLendMapper());
  30:              modelBuilder.Configurations.Add(new BookTypeMapper());
  31:              modelBuilder.Configurations.Add(new BookPlaceMapper());
  32:              modelBuilder.Configurations.Add(new StudentMapper());
  33:              modelBuilder.Configurations.Add(new ManagerMapper());
  34:              base.OnModelCreating(modelBuilder);
  35:          }
  36:   
  37:          public new IDbSet<T> Set<T>() where T : class
  38:          {
  39:              return base.Set<T>();
  40:          }
  41:      }
  42:  }

这里说明一下,OnModelCreating主要用于配置数据库实体类映射,我们可以把自定义的配置添加进来,最后通过调用OnModelCreating方法来触发数据库表创建事件。

至于Repository模式,则主要提供数据操作集合:

   1:  using System;
   2:  using System.Linq;
   3:  using System.Linq.Expressions;
   4:   
   5:  namespace TinyFrame.Data.DataRepository
   6:  {
   7:      public interface IRepository<T> where T:class
   8:      {
   9:          T GetByID(long id);
  10:          T GetByID(int id);
  11:          T GetByID(Guid id);
  12:          T GetByID(string id);
  13:          T Get(Expression<Func<T, bool>> where);
  14:          IQueryable<T> GetMany(Expression<Func<T, bool>> where);
  15:   
  16:          void Insert(T entity);
  17:          void Update(T entity);
  18:          void Delete(T entity);
  19:          void Delete(Expression<Func<T, bool>> where);
  20:      }
  21:  }

其具体的实现如下:

   1:  using System;
   2:  using System.Linq;
   3:  using System.Data.Entity;
   4:  using System.Linq.Expressions;
   5:  using System.Data.Entity.Validation;
   6:  using TinyFrame.Data.DataContext;
   7:   
   8:  namespace TinyFrame.Data.DataRepository
   9:  {
  10:      public class Repository<T>:IRepository<T> where T:class
  11:      {
  12:          public Repository(IDbContext context)
  13:          {
  14:              this.context = context;
  15:          }
  16:   
  17:          private IDbContext context;
  18:   
  19:          private IDbSet<T> dbset;
  20:          public virtual IDbSet<T> DbSet
  21:          {
  22:              get
  23:              {
  24:                  if (dbset == null)
  25:                      dbset = context.Set<T>();
  26:                  return dbset;
  27:              }
  28:          }
  29:   
  30:          public virtual T GetByID(long id)
  31:          {
  32:              return DbSet.Find(id);
  33:          }
  34:   
  35:          public virtual T GetByID(int id)
  36:          {
  37:              return DbSet.Find(id);
  38:          }
  39:   
  40:          public virtual T GetByID(Guid id)
  41:          {
  42:              return DbSet.Find(id);
  43:          }
  44:   
  45:          public virtual T GetByID(string id)
  46:          {
  47:              return DbSet.Find(id);
  48:          }
  49:   
  50:          public virtual T Get(Expression<Func<T, bool>> where)
  51:          {
  52:              return DbSet.Where(where).FirstOrDefault<T>();
  53:          }
  54:   
  55:          public virtual IQueryable<T> GetMany(Expression<Func<T, bool>> where)
  56:          {
  57:              return DbSet.Where(where);
  58:          }
  59:   
  60:          public virtual void Insert(T entity)
  61:          {
  62:              try
  63:              {
  64:                  if (entity == null)
  65:                      throw new ArgumentException("实体类为空");
  66:                  DbSet.Add(entity);
  67:                  context.SaveChanges();
  68:              }
  69:              catch (DbEntityValidationException dbex)
  70:              {
  71:                  var msg = string.Empty;
  72:                  foreach(var validationErrors in dbex.EntityValidationErrors)
  73:                      foreach(var validateionError in validationErrors.ValidationErrors)
  74:                          msg+=string.Format("Property:{0} Error:{1}",validateionError.PropertyName,validateionError.ErrorMessage);
  75:   
  76:                  var fail = new Exception(msg,dbex);
  77:                  throw fail;
  78:              }
  79:          }
  80:   
  81:          public virtual void Update(T entity)
  82:          {
  83:              try
  84:              {
  85:                  if (entity == null)
  86:                      throw new ArgumentNullException("实体类为空");
  87:                  context.SaveChanges();
  88:              }
  89:              catch (DbEntityValidationException dbex)
  90:              {
  91:                  var msg = string.Empty;
  92:                  foreach (var validationErrors in dbex.EntityValidationErrors)
  93:                      foreach (var validateionError in validationErrors.ValidationErrors)
  94:                          msg += string.Format("Property:{0} Error:{1}", validateionError.PropertyName, validateionError.ErrorMessage);
  95:   
  96:                  var fail = new Exception(msg, dbex);
  97:                  throw fail;
  98:              }
  99:          }
 100:   
 101:          public virtual void Delete(T entity)
 102:          {
 103:              try
 104:              {
 105:                  if (entity == null)
 106:                      throw new ArgumentNullException("实体类为空");
 107:                  DbSet.Remove(entity);
 108:                  context.SaveChanges();
 109:              }
 110:              catch (DbEntityValidationException dbex)
 111:              {
 112:                  var msg = string.Empty;
 113:                  foreach (var validationErrors in dbex.EntityValidationErrors)
 114:                      foreach (var validateionError in validationErrors.ValidationErrors)
 115:                          msg += string.Format("Property:{0} Error:{1}", validateionError.PropertyName, validateionError.ErrorMessage);
 116:   
 117:                  var fail = new Exception(msg, dbex);
 118:                  throw fail;
 119:              }
 120:          }
 121:   
 122:          public virtual void Delete(Expression<Func<T, bool>> where)
 123:          {
 124:              try
 125:              {
 126:                  var entities = DbSet.Where(where);
 127:                  foreach (var entity in entities.ToList())
 128:                      DbSet.Remove(entity);
 129:                  context.SaveChanges();
 130:              }
 131:              catch (DbEntityValidationException dbex)
 132:              {
 133:                  var msg = string.Empty;
 134:                  foreach (var validationErrors in dbex.EntityValidationErrors)
 135:                      foreach (var validateionError in validationErrors.ValidationErrors)
 136:                          msg += string.Format("Property:{0} Error:{1}", validateionError.PropertyName, validateionError.ErrorMessage);
 137:   
 138:                  var fail = new Exception(msg, dbex);
 139:                  throw fail;
 140:              }
 141:          }
 142:      }
 143:  }

由于在编码中,我们使用了泛型对象,所以让数据库中有表变动的时候,不会影响到我们这层。

最后是Unitofwork,这个比较简单,主要用于事务控制:

   1:  namespace TinyFrame.Data.DataUnitOfWork
   2:  {
   3:      public interface IUnitOfWork
   4:      {
   5:          void Commit();
   6:      }
   7:  }

一旦有批量的数据CRUD的时候,我们可以调用此方法进行批量提交,这样能够保证CRUD的准确性。

TinyFrame升级之二:数据底层访问部分的更多相关文章

  1. Memcached存Session数据、访问安全性、使用场景总结(3)

    最近做了一个单点登录SSO,登陆后的凭证放到Memcached令牌放到Cookies:但是用户经常掉线,开发环境和测试却没有这个问题,最后从Memcached找到原因. Memcached概念.作用. ...

  2. zoeDylan.js框架-数据底层

    zoeDylan.js是墨芈自己写的一套前端框架,不过由于墨芈经验不足,所以框架内部代码有些混乱. 墨芈写这套框架的目的是为了存储以后做前端开发过程中的一些代码,简单的说这套框架就是一个大杂烩. 这套 ...

  3. Android版本升级同时Sqlite数据库的升级及之前数据的保留

    http://www.cnblogs.com/wang340/archive/2013/05/06/3063135.html http://www.eoeandroid.com/forum.php?m ...

  4. 图解Janusgraph系列-图数据底层序列化源码分析(Data Serialize)

    图解Janusgraph系列-图数据底层序列化源码分析(Data Serialize) 大家好,我是洋仔,JanusGraph图解系列文章,实时更新~ 图数据库文章总目录: 整理所有图相关文章,请移步 ...

  5. Vue父子组件通信(父级向子级传递数据、子级向父级传递数据、Vue父子组件存储到data数据的访问)

    Vue父子组件通信(父级向子级传递数据.子级向父级传递数据.Vue父子组件存储到data数据的访问) 一.父级向子级传递数据[Prop]: ● Prop:子组件在自身标签上,使用自定义的属性来接收外界 ...

  6. Java学习-028-JSON 之二 -- 数据读取

    JSON数据由 JSONObject.JSONArray.key_value 组合而成.通常来说,JSONObject 可以包含 JSONObject.JSONArray.key_value:JSON ...

  7. 基于单例使用ThreadLocal对多线程下数据的访问修改

    package cn.lyy.thread; import java.util.Random; /** * 基于单例模式的基础上,使用ThreadLocal为每一个进入的线程生成一个实例, * 用来对 ...

  8. Tracert(跟踪路由)是路由跟踪实用程序,用于确定 IP 数据包访问目标所采取的路径。

    Tracert(跟踪路由)是路由跟踪实用程序,用于确定 IP 数据包访问目标所采取的路径.   Tracert 命令用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其 ...

  9. 利用AMPScript获取Uber用户数据的访问权限

    现代项目开发和资产管理方法正在不停地快速变化.在这场创新和扩张的竞赛中,新资产被迅速部署并暴露于公共互联网,已有资产也在不断发展. 要跟上这个不断变化的攻击面是很难的,更不用说保护这些应用程序和系统了 ...

随机推荐

  1. Swift中的类和结构体的相同点与不同点

     相同点: 1.都是有内部变量和函数 2.都可以有内部下标方式去取属性 3.都可以有初始化函数 4.都可以用协议   不同点: 1.类有继承 2.类可以多重引用 3.类有析构  

  2. UVa 111 - History Grading (by 最长公共子序列 )

     History Grading  Background Many problems in Computer Science involve maximizing some measure accor ...

  3. javascript之工厂方式定义对象

    每一个函数对象都有一个length属性,表示该函数期望接收的参数个数. <html> <head> <script type="text/javascript& ...

  4. MyCat 学习笔记 第十篇.数据分片 之 ER分片

    1 应用场景 这篇来说下mycat中自带的er关系分片,所谓er关系分片即可以理解为有关联关系表之间数据分片.类似于订单主表与订单详情表间的分片存储规则. 本文所说的er分片分为两种: a. 依据主键 ...

  5. emacs下安装pip

    Ubuntu13.10下安装pip的方法   $ sudo apt-get install python-pip python-dev build-essential  $ sudo pip inst ...

  6. Linux / OS X 实用命令

    具体可用参数还是用man指令查方便一点,在此不一一列出 图片来自imooc 磁盘相关: df 查看硬盘分区情况,实例 df -h du 查看文件大小情况 du -s /Directory 用户/用户组 ...

  7. Asp.net web form 动态生成控件的注意事项

    Asp.net页面生命周期 页面初始化          Page_Init   加载View State      LoadViewState    回发数据处理      LoadPostData ...

  8. 【ASP.NET 进阶】定时执行任务

    原理:利用全局应用程序类 Global.asax 和 System.Timers.Timer  类定时处理任务. 示例效果图: 其 Global.asax 类代码如下: using System; u ...

  9. Verilog (二) multiplexer and decoder

    1  mutiplexer 数据选择器 1)  one-bit wide 2-1 mux wire dout = sel? din1 : din0; // conditional continuous ...

  10. 【转】dsadd user批量创建AD用户命令详解

    常见的批量创建用户的方法有四种: 一. 帐户模板的方式 二. CSVDE和LDIFDE 三. 脚本的方式 四. DSADD 但是很少有详细的资料使用DSADD的方式来批量创建帐户,那么我就把我近期使用 ...