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的准确性。

上一篇:mysql中sql语句中常见的group_concat()函数意思以及用法,oracle中与其一样的功能函数是wmsys.wm_concat()


下一篇:SCOI 2019 划水记