TinyFrame升级之二:数据底层访问部分
在上一篇中,我列举了框架的整体结构,下面我们将一一说明:
首先需要说明的是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升级之二:数据底层访问部分的更多相关文章
- Memcached存Session数据、访问安全性、使用场景总结(3)
最近做了一个单点登录SSO,登陆后的凭证放到Memcached令牌放到Cookies:但是用户经常掉线,开发环境和测试却没有这个问题,最后从Memcached找到原因. Memcached概念.作用. ...
- zoeDylan.js框架-数据底层
zoeDylan.js是墨芈自己写的一套前端框架,不过由于墨芈经验不足,所以框架内部代码有些混乱. 墨芈写这套框架的目的是为了存储以后做前端开发过程中的一些代码,简单的说这套框架就是一个大杂烩. 这套 ...
- Android版本升级同时Sqlite数据库的升级及之前数据的保留
http://www.cnblogs.com/wang340/archive/2013/05/06/3063135.html http://www.eoeandroid.com/forum.php?m ...
- 图解Janusgraph系列-图数据底层序列化源码分析(Data Serialize)
图解Janusgraph系列-图数据底层序列化源码分析(Data Serialize) 大家好,我是洋仔,JanusGraph图解系列文章,实时更新~ 图数据库文章总目录: 整理所有图相关文章,请移步 ...
- Vue父子组件通信(父级向子级传递数据、子级向父级传递数据、Vue父子组件存储到data数据的访问)
Vue父子组件通信(父级向子级传递数据.子级向父级传递数据.Vue父子组件存储到data数据的访问) 一.父级向子级传递数据[Prop]: ● Prop:子组件在自身标签上,使用自定义的属性来接收外界 ...
- Java学习-028-JSON 之二 -- 数据读取
JSON数据由 JSONObject.JSONArray.key_value 组合而成.通常来说,JSONObject 可以包含 JSONObject.JSONArray.key_value:JSON ...
- 基于单例使用ThreadLocal对多线程下数据的访问修改
package cn.lyy.thread; import java.util.Random; /** * 基于单例模式的基础上,使用ThreadLocal为每一个进入的线程生成一个实例, * 用来对 ...
- Tracert(跟踪路由)是路由跟踪实用程序,用于确定 IP 数据包访问目标所采取的路径。
Tracert(跟踪路由)是路由跟踪实用程序,用于确定 IP 数据包访问目标所采取的路径. Tracert 命令用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其 ...
- 利用AMPScript获取Uber用户数据的访问权限
现代项目开发和资产管理方法正在不停地快速变化.在这场创新和扩张的竞赛中,新资产被迅速部署并暴露于公共互联网,已有资产也在不断发展. 要跟上这个不断变化的攻击面是很难的,更不用说保护这些应用程序和系统了 ...
随机推荐
- iOS label根据显示内容自适应大小
- (void)setupLabel { //准备工作 UILabel *textLabel = [[UILabel alloc] init]; textLabel.font = [UIFont sy ...
- iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载+使用输出流代替文件句柄
前言:本篇讲解,在前篇iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载的基础上,使用输出流代替文件句柄实现大文件断点续传. 在实际开发中,输入输出流用的比较少,但 ...
- 通过JAVA反射,调用未知类的类方法
下面是一个比较简单的通过JAVA的反射机制调用已知方法的例子 package com.togeek.mvntest; import java.lang.reflect.InvocationTarget ...
- 最近开始研究PMD(一款采用BSD协议发布的Java程序代码检查工具)
PMD是一款采用BSD协议发布的Java程序代码检查工具.该工具可以做到检查Java代码中是否含有未使用的变量.是否含有空的抓取块.是否含有不必要的对象等.该软件功能强大,扫描效率高,是Java程序员 ...
- 每日Scrum--No.8
Yesterday:学习和编写程序 Today:总结这次的冲刺和以及测试版的初步完成 Problem:在图的设计过程中掌握了图的基本运算函数的算法的理解和程序的有效吸收,包括图的深度和广度优先的遍历, ...
- Erlang数据类型的表示和实现(4)——boxed 对象
Boxed 对象 Boxed 对象是比较复杂的对象,在 Erlang 中主标签为 10 的 Eterm 表示一个对 boxed 对象的引用.这个 Eterm 除去标签之后剩下的实际上是一个指针,指向具 ...
- html的<head><title><meta>
head <head>用来标记HTML的头部,里面通常需要包括标题,基础信息,源信息等,定义在HTML头部的内容往往不会在网页上直接显示 title <title>的内容设置在 ...
- 对Jena的简单理解和一个例子
本文简单介绍Jena(Jena 2.4),使用Protégé 3.1(不是最新版本)创建一个简单的生物(Creature)本体,然后参照Jena文档中的一个例子对本体进行简单的处理,输出本体中的Cla ...
- nodejs 导出excel
nodejs 对查询数据生成excel并下载,采用方式先生成本excel文件,然后再下载:通过比较采用excel-export插件代码如下: excel.js代码: var extend = requ ...
- hdu 4635 Strongly connected 强连通缩点
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给你一个n个点m条边的图,问在图不是强连通图的情况下,最多可以向图中添多少条边,若图为原来 ...