本人之前一直写的都是Java的Dao和Manager不知.NET中的DAL是否也如下,若有不对,请各位园友们指出,谢谢~
先放上接口
public interface IDAL<PK, E> where PK : struct where E : class, new() { int Save(E entity); int Update(E entity); int Update(E entity, string[] propertys); int Delete(E entity); int Delete(PK id); IList<E> GetDatas(); IList<E> GetDatas(Expression<Func<E, bool>> predicate); IList<T> GetDatas<T>(Expression<Func<E, bool>> predicate, Expression<Func<E, T>> selector); E GetById(PK id); int ExecuteRawCommand(string sql, params object[] parameters); IList<E> SqlQuery(string sql, params object[] parameters); }
然后下面该类是基础操作类,实现了部分CRUD的操作,其余的操作,可以在具体实现类中完成
public abstract class AbstractBaseDAL<PK, E> : IDAL<PK, E> where PK : struct where E : class, new() { public const string PK_ID = "Id"; public Type GetEntityType() { return typeof(E); } /// <summary> /// 保存一条新的记录 /// </summary> /// <param name="entity"></param> /// <returns></returns> public int Save(E entity) { int changeCount = 0; using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required)) { using (YzOASysEntities context = new YzOASysEntities()) { context.Set<E>().Add(entity); changeCount = context.SaveChanges(); if (changeCount > 0) transaction.Complete(); } } return changeCount; } /// <summary> /// 修改一个实体 /// </summary> /// <param name="entity"></param> /// <returns></returns> public int Update(E entity) { int changeCount = 0; using(TransactionScope transaction = new TransactionScope (TransactionScopeOption.Required)) { using (YzOASysEntities context = new YzOASysEntities()) { context.Set<E>().Attach(entity); if (context.Entry<E>(entity).State == EntityState.Unchanged) context.Entry<E>(entity).State = EntityState.Modified; changeCount = context.SaveChanges(); if (changeCount > 0) transaction.Complete(); } } return changeCount; } /// <summary> /// 修改一个实体,只修改传入的书包含有该属性名的字段 /// </summary> /// <param name="entity"></param> /// <param name="propertys"></param> /// <returns></returns> public int Update(E entity, string[] propertys) { int changeCount = 0; using(TransactionScope transaction = new TransactionScope (TransactionScopeOption.Required)) { using (YzOASysEntities context = new YzOASysEntities()) { context.Set<E>().Attach(entity); IObjectContextAdapter objectContextAdatper = context; ObjectContext objectContext = objectContextAdatper.ObjectContext; ObjectStateEntry ose = objectContext.ObjectStateManager.GetObjectStateEntry(entity); foreach (string property in propertys) { ose.SetModifiedProperty(property); } if (context.Entry<E>(entity).State == EntityState.Unchanged) context.Entry<E>(entity).State = EntityState.Modified; changeCount = context.SaveChanges(); if (changeCount > 0) transaction.Complete(); } } return changeCount; } /// <summary> /// 根据一个实体删除一个记录 /// </summary> /// <param name="entity"></param> /// <returns></returns> public int Delete(E entity) { int changeCount = 0; using(TransactionScope transaction = new TransactionScope (TransactionScopeOption.Required)) { using (YzOASysEntities context = new YzOASysEntities()) { context.Set<E>().Attach(entity); if (context.Entry<E>(entity).State == EntityState.Unchanged) context.Entry<E>(entity).State = EntityState.Deleted; context.Set<E>().Remove(entity); try { changeCount = context.SaveChanges(); } catch (DbUpdateConcurrencyException ex) { } if (changeCount > 0) transaction.Complete(); } } return changeCount; } /// <summary> /// 根据主键ID删除一个记录 /// </summary> /// <param name="id"></param> /// <returns></returns> public int Delete(PK id) { int changeCount = 0; using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required)) { using (YzOASysEntities context = new YzOASysEntities()) { E e = new E(); PropertyInfo pi = e.GetType().GetProperty(PK_ID); pi.SetValue(e, id, null); context.Set<E>().Attach(e); if (context.Entry<E>(e).State == EntityState.Unchanged) context.Entry<E>(e).State = EntityState.Deleted; context.Set<E>().Remove(e); try { changeCount = context.SaveChanges(); } catch (DbUpdateConcurrencyException ex) { } if (changeCount > 0) transaction.Complete(); } } return changeCount; } /// <summary> /// 获取当前实体的所有集合数据 /// </summary> /// <returns></returns> public IList<E> GetDatas() { using (YzOASysEntities context = new YzOASysEntities()) { return context.Set<E>().ToList(); } } /// <summary> /// 根据linq条件查询实体集合数据 /// </summary> /// <param name="predicate"></param> /// <returns></returns> public IList<E> GetDatas(Expression<Func<E, bool>> predicate) { using (YzOASysEntities context = new YzOASysEntities()) { return context.Set<E>().Where(predicate).ToList(); } } /// <summary> /// 根据linq条件查询并返回实体的指定字段的数据集合 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="predicate"></param> /// <param name="selector"></param> /// <returns></returns> public IList<T> GetDatas<T>(Expression<Func<E, bool>> predicate, Expression<Func<E, T>> selector) { using (YzOASysEntities context = new YzOASysEntities()) { return context.Set<E>().Where(predicate).Select(selector).ToList(); } } /// <summary> /// 根据实体ID查找一条记录 /// </summary> /// <param name="id"></param> /// <returns></returns> public E GetById(PK id) { using (YzOASysEntities context = new YzOASysEntities()) { return context.Set<E>().Find(id); } } /// <summary> /// 操作原生SQL /// </summary> /// <param name="sql"></param> /// <param name="parameters"></param> /// <returns></returns> public int ExecuteRawCommand(string sql, params object[] parameters) { using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required)) { using (YzOASysEntities context = new YzOASysEntities()) { return context.Database.ExecuteSqlCommand(sql, parameters); } } } public IList<E> SqlQuery(string sql, params object[] parameters) { using (YzOASysEntities context = new YzOASysEntities()) { return context.Database.SqlQuery<E>(sql, parameters).ToList(); } } }
值得注意的是public int Update(E entity, string[] propertys)该方法,因为entityframework4.x/5.0是基于DbContext,而4.0是基于ObjectContext,其实DbContext是ObjectContext的上一层封装,简化并优化了entityframework的效率,但实际操作还是必须通过ObjectContext完成,又因为DbContext实现了IObjectContextAdapter接口,我们可以通过该接口获取到ObjectContext对象,那这一切都变的好办了.通过ObjectContext我们可以获得当前上下文中的ObjectStateEntry,该对象也就是当前entity的所有状态所在,我们可以通过设置当期entity的ModifiedProperty达到指定修改某字段的效果.其实我代码中的
if (context.Entry<E>(entity).State == EntityState.Unchanged) context.Entry<E>(entity).State = EntityState.Modified;
这段完全可以删除,因为当我们设置ModifiedProperty时,entityframework已经帮我们自动同步entity的State为Modified了.
小弟的C#资历尚浅,entityframework研究得也不够透彻,只懂皮毛,若有什么不对的地方,请各位园友,牛人们指出.谢谢~