中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

Lind.DDD.ILogicDeleteBehavor~邏輯刪除的實現

回到目錄

關于邏輯刪除

對(dui)于邏輯(ji)刪除(chu)之(zhi)前的(de)(de)做(zuo)(zuo)(zuo)法是(shi)(shi)在(zai)(zai)實(shi)體類中加(jia)個(ge)(ge)字(zi)段,一般是(shi)(shi)status,其(qi)中一種(zhong)(zhong)狀態是(shi)(shi)刪除(chu),當然也有其(qi)它做(zuo)(zuo)(zuo)法,如加(jia)個(ge)(ge)bool的(de)(de)字(zi)段IsDeleted,這些其(qi)實(shi)都(dou)過于武斷,即它在(zai)(zai)基類里加(jia)上后,所(suo)以實(shi)體類都(dou)會有這種(zhong)(zhong)特性,而(er)對(dui)于現(xian)實(shi)的(de)(de)數(shu)據表(biao),可能不顯示(shi)這種(zhong)(zhong)邏輯(ji)刪除(chu)的(de)(de)特性,如關系表(biao),日(ri)志表(biao),可能刪除(chu)就是(shi)(shi)物(wu)理上的(de)(de)直接(jie)delete,而(er)這種(zhong)(zhong)刪除(chu)字(zi)段加(jia)上去,我們的(de)(de)做(zuo)(zuo)(zuo)也是(shi)(shi)在(zai)(zai)業務層手動調用update方法,或者在(zai)(zai)底層提(ti)供(gong)一個(ge)(ge)delete方法的(de)(de)重載,總之(zhi),感覺不是(shi)(shi)很爽!

看了ABP的(de)軟刪(shan)除(chu)之(zhi)后(hou),對(dui)大叔有(you)了新的(de)啟發,即(ji)提出(chu)一(yi)個邏輯刪(shan)除(chu)的(de)接口,所以(yi)需要這個字段(duan)的(de)實(shi)體(ti)都去實(shi)現這個接口即(ji)可!

邏輯刪除的接口(對實體屬性的裝飾)

   /// <summary>
    /// 具有邏輯(ji)刪(shan)除(chu)的接口(kou),實體需(xu)要實現這個接口(kou),將IsDeleted實現
    /// 在倉儲實現類中,delete方法判(pan)斷實體是否實現了(le)ILogicDeleteBehavor這個接口(kou),然后再決(jue)定是否邏(luo)輯刪(shan)除
    /// </summary>
    public interface ILogicDeleteBehavor
    {
        /// <summary>
        /// 是否已經刪(shan)除,默認為false
        /// </summary>
        bool IsDeleted { get; set; }
    }

這個接口很干凈,只有一個屬性,這個屬性用來標識刪除的狀態,true表示已經刪除,在進行select操作時我們需要將這個狀態過濾,在delete方法里,我們也可以通過判斷當前實體是否屬于ILogicDeleteBehavor接口(kou)而對它采取是(shi)否(fou)進行邏輯刪(shan)除(chu)!

實體多繼承一個接口,完成某個特定的功能

 public partial class WebManageUsers :
        Lind.DDD.Domain.Entity,
        ILogicDeleteBehavor,
        IStatusBehavor
    {
        #region IStatusBehavor 成員

        public Status DataStatus { get; set; }

        #endregion

        #region ILogicDeleteBehavor 成員

        public bool IsDeleted { get; set; }

        #endregion
        public WebManageUsers()
        {
            this.WebManageRoles = new HashSet<WebManageRoles>();
            this.WebDepartments = new HashSet<WebDepartments>();
        }
        [DisplayName("登陸(lu)名"), Required]
        public string LoginName { get; set; }
        [DisplayName("密碼"), Required]
        public string Password { get; set; }
        [DisplayName("真實姓名(ming)"), Required]
        public string RealName { get; set; }
        [DisplayName("手(shou)機")]
        public string Mobile { get; set; }
        [DisplayName("電子郵(you)件")]
        public string Email { get; set; }
        [DisplayName("描述(shu)")]
        public string Description { get; set; }
        [DisplayName("操作者")]
        public string Operator { get; set; }
        [DisplayName("所屬項目")]
        public Nullable<int> WebSystemID { get; set; }
        public virtual ICollection<WebManageRoles> WebManageRoles { get; set; }
        public virtual ICollection<WebDepartments> WebDepartments { get; set; }

    }

本例采(cai)用的(de)是(shi)EF的(de)CodeFirst方式(shi),所以需要將自己定義實(shi)體,然后根據實(shi)體自動生成(cheng)數據庫.

刪除方法直接判斷實體是否實現了某個接口

 public void Delete(TEntity item)
        {
            if (item != null)
            {
                if (item is ILogicDeleteBehavor)
                {
                    //邏(luo)輯刪除(chu)
                    var pkList = GetPrimaryKey().Select(i => i.Name);
                    var entityType = typeof(TEntity);
                    List<object> primaryArr = new List<object>();
                    foreach (var primaryField in pkList)
                    {
                        primaryArr.Add(entityType.GetProperty(primaryField).GetValue(item, null));
                    }
                    var old = this.Find(primaryArr.ToArray());
                    (old as ILogicDeleteBehavor).IsDeleted = true;
                    this.Update(old);
                }
                else
                {
                    //物理刪除
                    Db.Set<TEntity>().Attach(item as TEntity);
                    Db.Entry(item).State = EntityState.Deleted;
                    Db.Set<TEntity>().Remove(item as TEntity);
                    this.SaveChanges();
                }

            }
        }

上面(mian)的設置,對(dui)于在(zai)列表里(li)(li)刪除某個對(dui)象已經可以實現了,而(er)如(ru)何(he)去(qu)過(guo)濾(lv)列表里(li)(li)的記錄呢,當(dang)然直接在(zai)DbSet<TEntity>()里(li)(li)去(qu)過(guo)濾(lv)是最(zui)好的,但沒(mei)有(you)直接的方式,因為我(wo)們的IsDeleted屬性沒(mei)有(you)對(dui)外暴(bao)露,而(er)對(dui)于Linq to Entity來說(shuo),你無法在(zai)查詢表達式中輸(shu)

入EDM之(zhi)外的(de)元素名(那也不認,它只認實體(ti)類型),還好在ABP里我找到了不錯的(de)方(fang)法,就是在數(shu)據上下(xia)文(wen)的(de)OnModelCreating方(fang)法上,添加過濾(lv)器,這個(ge)過濾(lv)器需要(yao)我們(men)安(an)裝EntityFramework.DynamicFilters包,直接用Nuget可(ke)以(yi)安(an)裝.

ModelBuilder.Filter完成對集合的全局過濾

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
   {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Filter("LogicDelete", (Lind.DDD.Domain.ILogicDeleteBehavor d) => d.IsDeleted, false);
   }

這樣在(zai)所有Linq Select語句之前都會(hui)添加d.IsDeleted==false這個參數完(wan)成邏輯刪除的過(guo)濾功能(neng)!

是不是很爽,很酷!

對于實體中其它的比較有特點的屬性,而又不是全局的屬性,我們都可以使用接口的方式進行定義,這類似于裝飾模式,即將某個屬性裝飾成某個接口,而在程序的另一端直接去操作這個接口即可

回到目錄

posted @ 2016-06-13 14:02  張占嶺  閱讀(2101)  評論(6)    收藏  舉報