本人之前一直寫的都是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研究得也不夠透徹,只懂皮毛,若有什么不對的地方,請各位園友,牛人們指出.謝謝~