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

首先需要说明的是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. IOS开发之SVN的使用

    关于SVN的一个使用细节    

  2. java基础--温故而知新 (01)

    1 myeclipse是一个eclipse插件.使用java语言开发.进程是javaw.exe--非命令行方式启动.   2 考这些术语的公司,往往都是世界一流的好公司.(技术广度+英语) java ...

  3. javascript 全局变量 局部变量 var 与不加var的区别

      一.外部的为全局,内部的为局部变量.   二.加var为局部变量(在方法内),不加var为全局变量(当方法内有一次使用后) <script type="text/javascrip ...

  4. 整理了一些jQuery关于事件冒泡和事件委托的技巧

    首先,大家都知道,jQuery事件触发时有2种机制,一种是事件委托,另一种是事件冒泡(IE情况暂时不考虑).拿click事件做例子,先附上一段代码: html: <body> <di ...

  5. Git哲学与使用

    -- 故国神游,多情应笑我,早生华发. Git是什么? Git是一个版本控制工具,代码管理工具,团队协作工具.它跟SVN等传统工具实现同样的目的:但从某种程度来说,它更快,更灵活.我想绝大多数读者都已 ...

  6. Nuget~管理自己的包包~丢了的包包快速恢复

    之前写过一篇Nuget~管理自己的包包的文章,今天来讲Nuget的另一个东西,就是找回丢失的DLL,我们在引用包包后,在当前解决方案根目录就生成一个packages的目前,里面有我们从nuget下载的 ...

  7. rowcount和@@Rowcount的区别,获取insert、update、delete影响行数

    rowcount的用法: rowcount的作用就是用来限定后面的sql在返回指定的行数之后便停止处理,比如下面的示例, set rowcount 10select * from 表A 这样的查询只会 ...

  8. Java Concurrency In Practice -Chapter 2 Thread Safety

    Writing thread-safe code is managing access to state and in particular to shared, mutable state. Obj ...

  9. Android程序入口以及项目文件夹的含义和使用总结—入门

    新接触一门程序或者开发框架,我一般都要先弄清楚程序的入口在哪里,程序怎么运行的:建立一个项目后,各个文件夹有什么作用以及如何使用等等.理清楚这些东西对以后开发是很有好处的,古话说得好,工欲善其事,必先 ...

  10. oracle数据库ORA-01654 错误的解决方法

    引言: 数据库突然报: ORA-01654: unable to extend index BO.INDEX_indexname by 311072 in tablespace 错误,上网查原因,发现 ...