Entity FrameWork(EF)6.0.2 增刪修讀(READ)的操作實現

第一步:首先創建一個接口,用以暴露其操作的方法

 public interface IOperate<TEntity>
    {
        List<TEntity> FindAll();
       // TEntity FindByKey(object key);
        int Add(TEntity entity);
        int AddRange(IEnumerable<TEntity> entities);
        int Delete(TEntity entity);
       // int DeleteByKey(object key);
      //  int ChangeStatus(object key, object status);
        int DeleteRange(IEnumerable<TEntity> entities);
        int Update(TEntity entity);
       // int Save(TEntity entity);
        int ExecuteSql(string cmdStr, object[] paras);
        List<TEntity> SqlQuery(string queryCmdStr, object[] paras);
    }

 

第二部:實現接口,也就是用EF實現數據庫的操作

 public class EfOperate<TEntity> : IOperate<TEntity> where TEntity : class
    {
        private VehicleCheckDBEntities _module;
        private static readonly object LockHelper = new object();

        public List<TEntity> SqlQuery(string queryCmdStr, object[] paras)
        {
            try
            {
                using (_module = new VehicleCheckDBEntities())
                {
                    return paras == null ? _module.Database.SqlQuery<TEntity>(queryCmdStr).ToList() : _module.Database.SqlQuery<TEntity>(queryCmdStr, paras).ToList();
                }
            }
            catch (Exception error)
            {

                throw new Exception(error.Message);
            }

        }

        /// <summary>
        /// 執行Sql語句
        /// </summary>
        /// <returns></returns>
        public int ExecuteSql(string cmdStr, object[] paras)
        {
            /*
            const string cmdStr = "update students set name=@name where id<=@id";
            var paras = new object[]
                {
                    new SqlParameter("@name","哈哈"),
                     new SqlParameter("@id",3)
                };
            */
          
            DbContextTransaction transaction = null;

            try
            {
                lock (LockHelper)
                {
                    using (_module = new VehicleCheckDBEntities())
                    {
                        using (transaction = _module.Database.BeginTransaction())
                        {
                            int rtnNUmber = paras == null
                                       ? _module.Database.ExecuteSqlCommand(cmdStr)
                                       : _module.Database.ExecuteSqlCommand(cmdStr, paras);
                            _module.SaveChanges();
                            transaction.Commit();
                            return rtnNUmber;
                        }
                    }
                }
              
            }
            catch (Exception error)
            {
                if (transaction != null)
                    transaction.Rollback();
                throw new Exception(error.Message);
            }

        }

        protected DbSet<TEntity> DbSet
        {

            get
            {
                try
                {
                    using (_module = new VehicleCheckDBEntities())
                    {
                        return _module.Set<TEntity>();
                    }
                }
                catch (Exception error)
                {
                    throw new Exception(error.Message);
                }

            }
        }

        public List<TEntity> FindAll()
        {
            try
            {
                using (_module = new VehicleCheckDBEntities())
                {
                    return _module.Set<TEntity>().ToList();
                }
            }
            catch (Exception error)
            {
                throw new Exception(error.Message);
            }
        }

 

        /// <summary>
        /// 添加記錄
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Add(TEntity entity)
        {
            #region 方法一 已測試
#if ceshi
            using (module = new EfModule())
            {
                var entry = module.Entry(entity);
                if (entry.State == EntityState.Detached)
                {
                    entry.State = EntityState.Added;
                }
                return module.SaveChanges();

            }
#endif
            #endregion

            #region 方法二 已測試

            DbContextTransaction transaction = null;
            try
            {
                using (_module = new VehicleCheckDBEntities())
                {
                    using (transaction = _module.Database.BeginTransaction())
                    {
                        _module.Set<TEntity>().Add(entity);
                        int rtnNumber = _module.SaveChanges();
                        transaction.Commit();
                        return rtnNumber;
                    }
                }
            }
            catch (Exception error)
            {
                if (transaction != null)
                    transaction.Rollback();
                throw new Exception(error.Message);
            }

            #endregion
        }

        /// <summary>
        /// 添加多條記錄
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public int AddRange(IEnumerable<TEntity> entities)
        {
            DbContextTransaction transaction = null;
            try
            {
                using (_module = new VehicleCheckDBEntities())
                {
                    using (transaction = _module.Database.BeginTransaction())
                    {
                        _module.Set<TEntity>().AddRange(entities);
                        int rtnNumber = _module.SaveChanges();
                        transaction.Commit();
                        return rtnNumber;
                    }
                }
            }
            catch (Exception error)
            {
                if (transaction != null)
                    transaction.Rollback();
                throw new Exception(error.Message);
            }

        }

        /// <summary>
        /// 修改記錄
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Update(TEntity entity)
        {
            //修改不像Add或Remove有直接的方法,所以必須更改記錄在上下文的狀態爲EntityState.Modified
            DbContextTransaction transaction = null;
            try
            {
                lock (LockHelper)
                {
                using (_module = new VehicleCheckDBEntities())
                {

                    using (transaction = _module.Database.BeginTransaction())
                    {

                        var entry = _module.Entry(entity);
                        if (entry.State == EntityState.Detached)
                        {
                            _module.Set<TEntity>().Attach(entity);
                            entry.State = EntityState.Modified;
                        }

                        int rtnNumber = _module.SaveChanges();
                        transaction.Commit();
                        return rtnNumber;
                    }
                      
                    }

                }
            }
            catch (Exception error)
            {
                if (transaction != null)
                    transaction.Rollback();
                throw new Exception(error.Message);
            }

        }

        /// <summary>
        /// 刪除記錄
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Delete(TEntity entity)
        {
            #region 方法一 已測試 優點:使用任何類;不足之處是要手動更改記錄在上下文的狀態爲 EntityState.Deleted,與修改原理一樣

            //using (module = new EfModule())
            //{
            //    var entry = module.Entry(entity);
            //    if (entry.State == EntityState.Detached)
            //    {
            //        entry.State = EntityState.Deleted;
            //    }
            //    return module.SaveChanges();

            //}

            #endregion

            #region 方法2 已測試  直接刪除,缺點: 只能使用Student類
            //using (EfModule module = new EfModule())
            //{
            //    var info = module.Students.Where(o => o.Id == 7).First();//若檢索到的對象是在using外面生成的,則會報錯
            //   module.Set<Student>().Remove(info);   //  module.Students.Remove(info); 兩者都可以
            //   return module.SaveChanges();
            //}
            #endregion

            #region 方法3 已測試  直接刪除,優點:使用任何類,把記錄直接添加到上下文中,當Remove時會把狀態自動改爲Deleted
            DbContextTransaction transaction = null;
            try
            {
                using (_module = new VehicleCheckDBEntities())
                {
                    using (transaction = _module.Database.BeginTransaction())
                    {
                        //if (_module.Set<TEntity>().Any(o => o.Id == entity.Id))
                        //{
                        _module.Set<TEntity>().Attach(entity);
                        _module.Set<TEntity>().Remove(entity);
                        int rtnNumber = _module.SaveChanges();
                        transaction.Commit();
                        return rtnNumber;
                        //}
                        //return 0;
                    }
                }
            }
            catch (Exception error)
            {
                if (transaction != null)
                    transaction.Rollback();
                throw new Exception(error.Message);
            }

            #endregion
        }

        /// <summary>
        /// 刪除多條記錄
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public int DeleteRange(IEnumerable<TEntity> entities)
        {
            DbContextTransaction transaction = null;
            try
            {
                using (_module = new VehicleCheckDBEntities())
                {
                    using (transaction = _module.Database.BeginTransaction())
                    {
                        foreach (var entity in entities)
                        {
                            //if (_module.Set<TEntity>().Any(o => o.Id == entity.Id))
                            //{
                            var entry = _module.Entry(entity);
                            if (entry.State == EntityState.Detached)
                            {
                                entry.State = EntityState.Deleted;
                            }
                            //}
                        }
                        int rtnNumber = _module.SaveChanges();
                        transaction.Commit();
                        return rtnNumber;

                    }
                }
            }
            catch (Exception error)
            {
                if (transaction != null)
                    transaction.Rollback();
                throw new Exception(error.Message);
            }

        }

    }

 

第三步:創建對象


        private static readonly IOperate<Device> DeviceOperate = new EfOperate<Device>();//創建操作表Device的對象
        public static readonly IOperate<DeviceDeny> DeviceDenyOperate = new EfOperate<DeviceDeny>();//創建操作表DeviceDeny的對象

 

第四步:調用對象的方法

  public int SaveDeviceDeny(DeviceDeny deviceDeny)
        {
            try
            {
                return deviceDeny.Id > 0 ? DeviceDenyOperate.Update(deviceDeny) : DeviceDenyOperate.Add(deviceDeny);
            }
            catch (Exception error)
            {
                throw new Exception(error.Message);
            }
        }
        public int ChangeStatus(int key, int status)
        {
            const string cmdStr = "update device set status=@status where id=@id";
            var paras = new object[]
                {
                    new SqlParameter("@status",status),
                     new SqlParameter("@id",key)
                };
            try
            {
                return DeviceOperate.ExecuteSql(cmdStr, paras);
            }
            catch (Exception error)
            {
                throw new Exception(error.Message);
            }
        
        }

        public int DeleteDevice(int key)
        {
             string cmdStr =string.Format( "delete device where id={0}",key);
            try
            {
                return DeviceOperate.ExecuteSql(cmdStr, null);
            }
            catch (Exception error)
            {
                throw new Exception(error.Message);
            }
          
        }

   public int SaveDevice(Device device)
        {
            if (device == null)
                return -1;
          
            try
            {
                if (device.Id > 0)
                {
                    const string cmdStr = "  update device set UsedTimes=isnull(UsedTimes,0)+1, LastUsingIp=@lastip,LastUsingDate=@lastdate ,LastUsingUserID=@userId where id=@id  ";
                    //var parameter = new object[]
                    //    {
                    //        new SqlParameter("@times", device.UsedTimes),
                    //        new SqlParameter("@lastip", device.LastUsingIp),
                    //        new SqlParameter("@lastdate", device.LastUsingDate),
                    //        new SqlParameter("@userId", device.LastUsingUserID),
                    //        new SqlParameter("@id", device.Id)

                    //    };
                    //return DeviceOperate.ExecuteSql(cmdStr, parameter);

                    var parameter = new DbParameter[]
                     {
                        new SqlParameter("@times", device.UsedTimes),
                         new SqlParameter("@lastip", device.LastUsingIp),
                         new SqlParameter("@lastdate", device.LastUsingDate),
                         new SqlParameter("@userId", device.LastUsingUserID),
                         new SqlParameter("@id", device.Id)

                     };
                    return DbHelper.ExecuteNonQuery(CommandType.Text, cmdStr, parameter);
                }
                return DeviceOperate.Add(device);
               
            }
            catch (Exception error)
            {
                throw new Exception(error.Message);
            }
        }

 

實踐心得:

首先說一下不足之處,就是在修改方法的實現還是不盡人意,當併發調用的時候,程序會報錯,大體的意思是當實體類里加載了一條記錄時,修改的時候可能由於對這條數據加了鎖,無法進行修改;第二個錯誤就是實體對象模型connection已經關閉,無法對其進行操作,但是ADD方法與Delete方法不會出現此錯誤,所以我在Update方法中加了Lock,錯誤便不會出現。也即下面代碼:

    /// <summary>
        /// 修改記錄
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Update(TEntity entity)
        {
            //修改不像Add或Remove有直接的方法,所以必須更改記錄在上下文的狀態爲EntityState.Modified
            DbContextTransaction transaction = null;
            try
            {
                lock (LockHelper)
                {
                using (_module = new VehicleCheckDBEntities())
                {

                    using (transaction = _module.Database.BeginTransaction())
                    {

                        var entry = _module.Entry(entity);
                        if (entry.State == EntityState.Detached)
                        {
                            _module.Set<TEntity>().Attach(entity);
                            entry.State = EntityState.Modified;
                        }

                        int rtnNumber = _module.SaveChanges();
                        transaction.Commit();
                        return rtnNumber;
                    }
                      
                    }

                }
            }
            catch (Exception error)
            {
                if (transaction != null)
                    transaction.Rollback();
                throw new Exception(error.Message);
            }

        }

 

PS:另如果有更優化方案,望請指點,知識用來分享,從而才能在知識中得到樂趣!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章