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