Back to Catalog
About logical deletion
The practice before the tombstone is to add a field to the entity class, usually the status, one of the states is deleted, of course, there are other practices, such as adding a bool field isdeleted, which is actually too arbitrary, that is, it is added to the base class, so the entity class will have this feature, And for the actual data table, may not display this kind of tombstone characteristics, such as relational table, log table, may be deleted is the physical direct Delete, and this delete field plus go, we do also in the business layer manually call the Update method, or provide a Delete method on the bottom of the overload, in short , the feeling is not very cool!
After looking at the ABP soft Delete, the uncle has a new inspiration, that is, to propose a logical deletion of the interface, so need this field entity to implement this interface can!
tombstoned interfaces (decoration of entity properties)
/// <summary> ///an interface with a tombstone, the entity needs to implement this interface, the isdeleted implementation///in the Warehousing implementation class, the Delete method determines whether the entity implements the Ilogicdeletebehavor interface, and then decides whether to delete the logical/// </summary> Public InterfaceIlogicdeletebehavor {/// <summary> ///is deleted, default is False/// </summary> BOOLIsDeleted {Get;Set; } }
This interface is clean, there is only one property, this property is used to identify the state of the deletion, true means that it has been deleted, we need to filter this state in the select operation, in the Delete method, we can also determine whether the current entity belongs to Ilogicdeletebehavor the interface and take it for logical deletion!
Entities inherit an interface more than one, accomplishing a specific function
Public Partial classWebManageUsers:Lind.DDD.Domain.Entity, Ilogicdeletebehavor, Istatusbehavor {#regionIstatusbehavor Members PublicStatus Datastatus {Get;Set; } #endregion #regionIlogicdeletebehavor Members Public BOOLIsDeleted {Get;Set; } #endregion Publicwebmanageusers () { This. Webmanageroles =NewHashset<webmanageroles>(); This. Webdepartments =NewHashset<webdepartments>(); } [DisplayName ("Login Name"), Required] Public stringLoginName {Get;Set; } [DisplayName ("Password"), Required] Public stringPassword {Get;Set; } [DisplayName ("real name"), Required] Public stringRealname {Get;Set; } [DisplayName ("Mobile Phone")] Public stringMobile {Get;Set; } [DisplayName ("Email")] Public stringEmail {Get;Set; } [DisplayName ("Description")] Public stringDescription {Get;Set; } [DisplayName ("by operator")] Public stringOperator {Get;Set; } [DisplayName ("Affiliated Projects")] Publicnullable<int> Websystemid {Get;Set; } Public VirtualIcollection<webmanageroles> Webmanageroles {Get;Set; } Public VirtualIcollection<webdepartments> webdepartments {Get;Set; } }
This example uses the EF codefirst approach, so you need to define the entity yourself and then automatically generate the database based on the entity.
The Delete method directly determines whether an entity implements an interface
Public voidDelete (TEntity item) {if(Item! =NULL) { if(item is Ilogicdeletebehavor) { //Logical Deletion varPklist = GetPrimaryKey (). Select (i =i.name); varEntityType =typeof(TEntity); List<Object> Primaryarr =Newlist<Object>(); foreach(varPrimaryfieldinchpklist) {Primaryarr.add (Entitytype.getproperty (Primaryfield). GetValue (item,NULL)); } varOld = This. Find (Primaryarr.toarray ()); ( old asIlogicdeletebehavor). IsDeleted =true; This. Update (old); } Else { //Physical deletionDb.set<tentity> (). Attach (item asTEntity); Db.entry (item). State=entitystate.deleted; Db.set<TEntity> (). Remove (item asTEntity); This. SaveChanges (); } } }
The above settings, for deleting an object in the list can be implemented, and how to filter the list of records, of course, directly in dbset<tentity> () to filter is the best, but there is no direct way, because our isdeleted property is not exposed to the external, For LINQ to entity, you cannot lose in a query expression
The name of the element outside the EDM (which is not recognized, it only recognized the entity type), fortunately in the ABP I found a good method, that is, in the data context of the Onmodelcreating method, add a filter, This filter requires us to install the Entityframework.dynamicfilters package, which can be installed directly with NuGet.
Modelbuilder.filter complete global filtering of the collection
protected Override void onmodelcreating (Dbmodelbuilder modelBuilder) { base. Onmodelcreating (ModelBuilder); Modelbuilder.filter ("logicdelete"false); }
This will add d.isdeleted==false to the filter function of the tombstone before all LINQ SELECT statements!
Isn't it cool?
For other attributes in the entity that are more characteristic than the global attribute, we can use the interface to define the way, which is similar to the decoration mode, a property is decorated as an interface, and at the other end of the program to operate the interface directly .
Back to Catalog
lind.ddd.ilogicdeletebehavor~ implementation of logical deletion