Entiy Framework研究 - 基础设施层
来源:互联网 发布:做广告牌用什么软件 编辑:程序博客网 时间:2024/04/30 21:09
基础设施层主要包含3个项目:
一、数据实体,对应到数据的表和视图
在这里有个基础实体类,用来限定repository的泛型实体传入,也重载了一些方法hashcode之类的,方便做数据实体比较,还有一个辅助生成主键的类,代码如下:
1. Entity类
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Chart.Workflow.Infrastructure.Data{ public class Entity { #region Members int? _requestedHashCode; string _Id; #endregion #region Properties /// <summary> /// Get the persisten object identifier /// </summary> public virtual string Id { get { return _Id; } protected set { _Id = value; } } #endregion #region Public Methods /// <summary> /// Check if this entity is transient, ie, without identity at this moment /// </summary> /// <returns>True if entity is transient, else false</returns> public bool IsTransient() { return string.IsNullOrEmpty(this.Id); } /// <summary> /// Generate identity for this entity /// </summary> public void GenerateNewIdentity() { if (IsTransient()) this.Id = IdentityGenerator.NewSequentialId(); } /// <summary> /// Change current identity for a new non transient identity /// </summary> /// <param name="identity">the new identity</param> public void ChangeCurrentIdentity(string identity) { if (!string.IsNullOrEmpty(this.Id)) this.Id = identity; } #endregion #region Overrides Methods /// <summary> /// <see cref="M:System.Object.Equals"/> /// </summary> /// <param name="obj"><see cref="M:System.Object.Equals"/></param> /// <returns><see cref="M:System.Object.Equals"/></returns> public override bool Equals(object obj) { if (obj == null || !(obj is Entity)) return false; if (Object.ReferenceEquals(this, obj)) return true; Entity item = (Entity)obj; if (item.IsTransient() || this.IsTransient()) return false; else return item.Id == this.Id; } /// <summary> /// <see cref="M:System.Object.GetHashCode"/> /// </summary> /// <returns><see cref="M:System.Object.GetHashCode"/></returns> public override int GetHashCode() { if (!IsTransient()) { if (!_requestedHashCode.HasValue) _requestedHashCode = this.Id.GetHashCode() ^ 31; // XOR for random distribution (http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx) return _requestedHashCode.Value; } else return base.GetHashCode(); } public static bool operator ==(Entity left, Entity right) { if (Object.Equals(left, null)) return (Object.Equals(right, null)) ? true : false; else return left.Equals(right); } public static bool operator !=(Entity left, Entity right) { return !(left == right); } #endregion }}
2. IdentityGenerator类
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Chart.Workflow.Infrastructure.Data{ public static class IdentityGenerator { /// <summary> /// This algorithm generates secuential strings across system boundaries, ideal for databases /// </summary> /// <returns></returns> public static string NewSequentialId() { string resut = Guid.NewGuid().ToString().Replace("-", ""); return resut; } /// <summary> /// This algorithm generates secuential strings across system boundaries, ideal for databases /// </summary> /// <returns></returns> public static Guid NewSequentialGuid() { byte[] uid = Guid.NewGuid().ToByteArray(); byte[] binDate = BitConverter.GetBytes(DateTime.UtcNow.Ticks); byte[] secuentialGuid = new byte[uid.Length]; secuentialGuid[0] = uid[0]; secuentialGuid[1] = uid[1]; secuentialGuid[2] = uid[2]; secuentialGuid[3] = uid[3]; secuentialGuid[4] = uid[4]; secuentialGuid[5] = uid[5]; secuentialGuid[6] = uid[6]; // set the first part of the 8th byte to '1100' so // later we'll be able to validate it was generated by us secuentialGuid[7] = (byte)(0xc0 | (0xf & uid[7])); // the last 8 bytes are sequential, // it minimizes index fragmentation // to a degree as long as there are not a large // number of Secuential-Guids generated per millisecond secuentialGuid[9] = binDate[0]; secuentialGuid[8] = binDate[1]; secuentialGuid[15] = binDate[2]; secuentialGuid[14] = binDate[3]; secuentialGuid[13] = binDate[4]; secuentialGuid[12] = binDate[5]; secuentialGuid[11] = binDate[6]; secuentialGuid[10] = binDate[7]; return new Guid(secuentialGuid); } }}
二、辅助切面,主要用来全局的东西:包含验证,日志,资源之类的;
基础方法如下:
三、数据上下文,主要是基础的数据访问操作实现
1. ISql接口,做sql语句查询使用,如下:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Chart.Workflow.Infrastructure.Context{ public interface ISql { IEnumerable<TEntity> ExecuteQuery<TEntity>(string sqlQuery, params object[] parameters); int ExecuteCommand(string sqlCommand, params object[] parameters); }}
2. IQueryUnitOfWork类,简单数据的操作,如下:
using System;using System.Collections.Generic;using System.Data.Entity;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Chart.Workflow.Infrastructure.Context{ public interface IQueryUnitOfWork:IUnitOfWork,ISql { DbSet<TEntity> CreateSet<TEntity>() where TEntity : class; void Attach<TEntity>(TEntity item) where TEntity : class; void SetModified<TEntity>(TEntity item) where TEntity : class; void ApplyCurrentValues<TEntity>(TEntity original, TEntity current) where TEntity : class; }}
3. IUnitOfWork接口,数据事务性操作,如下:
using System;using System.Collections.Generic;using System.Data.Entity;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Chart.Workflow.Infrastructure.Context{ public interface IUnitOfWork : IDisposable { void Commit(); void CommitAndRefreshChanges(); void RollbackChanges(); }}
4. UnitOfWork类,具体核心实现数据操作,如下:
using Chart.Workflow.Infrastructure.Data;using System;using System.Collections.Generic;using System.Data.Entity;using System.Data.Entity.Infrastructure;using System.Data.Entity.ModelConfiguration.Conventions;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Chart.Workflow.Infrastructure.Context{ public class UnitOfWork : DbContext, IQueryUnitOfWork { IDbSet<Student> _students; public IDbSet<Student> Students { get { if (_students == null) _students = base.Set<Student>(); return _students; } } IDbSet<Course> _course; public IDbSet<Course> Courses { get { if (_course == null) _course = base.Set<Course>(); return _course; } } public UnitOfWork() :base() { } public UnitOfWork(string connectionstring) :base(connectionstring) { } #region IQueryUnitOfWork Members public DbSet<TEntity> CreateSet<TEntity>() where TEntity : class { return base.Set<TEntity>(); } public void Attach<TEntity>(TEntity item) where TEntity : class { //attach and set as unchanged base.Entry<TEntity>(item).State = System.Data.EntityState.Unchanged; } public void SetModified<TEntity>(TEntity item) where TEntity : class { //this operation also attach item in object state manager base.Entry<TEntity>(item).State = System.Data.EntityState.Modified; } public void ApplyCurrentValues<TEntity>(TEntity original, TEntity current) where TEntity : class { //if it is not attached, attach original and set current values base.Entry<TEntity>(original).CurrentValues.SetValues(current); } public void Commit() { base.SaveChanges(); } public void CommitAndRefreshChanges() { bool saveFailed = false; do { try { base.SaveChanges(); saveFailed = false; } catch (DbUpdateConcurrencyException ex) { saveFailed = true; ex.Entries.ToList() .ForEach(entry => { entry.OriginalValues.SetValues(entry.GetDatabaseValues()); }); } } while (saveFailed); } public void RollbackChanges() { // set all entities in change tracker // as 'unchanged state' base.ChangeTracker.Entries() .ToList() .ForEach(entry => entry.State = System.Data.EntityState.Unchanged); } public IEnumerable<TEntity> ExecuteQuery<TEntity>(string sqlQuery, params object[] parameters) { if (parameters == null) { parameters = new object[0]; } return base.Database.SqlQuery<TEntity>(sqlQuery, parameters); } public int ExecuteCommand(string sqlCommand, params object[] parameters) { if (parameters == null) { parameters = new object[0]; } return base.Database.ExecuteSqlCommand(sqlCommand, parameters); } #endregion #region DbContext Overrides protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Remove unused conventions //OneToManyCascadeDeleteConvention modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); //数据库表和实体类型不一致使用 modelBuilder.Entity<Student>().ToTable("Student"); modelBuilder.Entity<Course>().ToTable("Course"); //数据库字段条件限制配置文件 modelBuilder.Configurations.Add(new StudentEntityTypeConfiguration()); modelBuilder.Configurations.Add(new CourseEntityTypeConfiguration()); } #endregion }}
- Entiy Framework研究 - 基础设施层
- Entiy Framework研究 - 项目架构搭建
- Android Framework 层研究网站
- 从View开始研究FrameWork层的源码
- 准备研究Android framework层 发此文小记一下
- 终于可以下载android源代码来开始研究framework层了
- remove entiy 注意点
- blueprint--css framework研究
- 【内核研究】Framework框架
- 【内核研究】Framework常见问题
- Spark FrameWork源码研究
- framework层开发
- Framework层基本架构
- android电池 framework层
- framework层服务分析
- android framework层
- android电池 framework层
- Application Framework层介绍
- jquery js 获取动态的json键值
- 学习记录:Hadoop之WordCount运行
- const 与指针
- 获取tr下面所有的checkbox的属性为checked的checkbox
- 获取windows系统版本信息
- Entiy Framework研究 - 基础设施层
- [bxd学习java基本点]7.linkedList方法,remove移走的要显示元素
- Linux的电源管理架构
- 做一个有理想的程序员(转)
- 作为一个程序员应该注意的地方
- 通过漫游配置文件
- 转的arcgis9.3全的安装信息
- 一个页面很长下面有提交按钮,提交后还在原位置的简单解决办法
- Linux中替换文本中的字符串