2016-01-21 25 views
8

Bir veritabanı yumuşak aşağıdaki öğretici kullanarak (silindi olarak girdileri işaretler bir boolean bayrak) silmek uygulamış çalışmıyor veritabanı önleme kullanarak uygulanmasını silmek bir silme işlemi, bir modele basitçe [SoftDelete("IsDeleted")] ek açıklama ekleyerek uygulanır. Sorun şu ana kadar çalışmıyor. https://github.com/rakeshbabuparuchuri/EFExpensionPointsVarlık Framework yumuşak

yumuşak projeme silmek uygularken yanlış bir şey yaptığını olursa benim koduna Bir bakabilir miyim:

kaynak güvenilir gözüküyor, hatta bununla da kalmayarak çözümün bir örneğini yayınladı?

[SoftDelete("IsDeleted")] 
public class BC_Instance 
{ 
    public int ID { get; set; } 
    public bool IsDeleted { get; set; } 
} 

ApplicationDbContext.cs:

namespace bcplatform2.Models 
{ 
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
    { 
     public ApplicationDbContext() 
      : base("DefaultConnection", throwIfV1Schema: false) 
     { 
     } 

     // Add a DbSet for each one of your Entities 
     //public DbSet<VirtualGuest> VirtualGuests { get; set; } 
     public DbSet<BC_Instance> BiocloudInstances { get; set; } 

     static ApplicationDbContext() 
     { 
      Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer()); 
     } 

     public static ApplicationDbContext Create() 
     { 
      return new ApplicationDbContext(); 
     } 

     protected new void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      var conv = new AttributeToTableAnnotationConvention<SoftDeleteAttribute, string>(
       "SoftDeleteColumnName", 
       (type, attributes) => attributes.Single().ColumnName); 

      modelBuilder.Conventions.Add(conv); 
     } 
    } 
} 

ApplicationDbConfiguration.cs

SoftDeleteAttribute.cs:

namespace bcplatform2.Helpers 
{ 
    public class SoftDeleteAttribute : Attribute 
    { 
     public SoftDeleteAttribute(string column) 
     { 
      ColumnName = column; 
     } 

     public string ColumnName { get; set; } 

     public static string GetSoftDeleteColumnName(EdmType type) 
     { 
      MetadataProperty annotation = type.MetadataProperties 
       .Where(p => p.Name.EndsWith("customannotation:SoftDeleteColumnName")) 
       .SingleOrDefault(); 

      return annotation == null ? null : (string)annotation.Value; 
     } 
    } 
} 

Bu

Modeli

SoftDeleteInterceptor.cs

Ben SoftDeleteAttribute.GetSoftDeleteColumnName(deleteCommand.Target.VariableType.EdmType) yumuşak silme ayrıntısını bulmak ve null döndürür olmadığını fark ettik. Ama nedenini bilmiyorum.

namespace bcplatform2.Helpers 
{ 
    public class SoftDeleteInterceptor : IDbCommandTreeInterceptor 
    { 
     public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext) 
     { 
      if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace) 
      { 
       var queryCommand = interceptionContext.Result as DbQueryCommandTree; 
       if (queryCommand != null) 
       { 
        var newQuery = queryCommand.Query.Accept(new SoftDeleteQueryVisitor()); 
        interceptionContext.Result = new DbQueryCommandTree(
         queryCommand.MetadataWorkspace, 
         queryCommand.DataSpace, 
         newQuery); 
       } 

       var deleteCommand = interceptionContext.OriginalResult as DbDeleteCommandTree; 
       if (deleteCommand != null) 
       { 
        var column = SoftDeleteAttribute.GetSoftDeleteColumnName(deleteCommand.Target.VariableType.EdmType); 
        if (column != null) 
        { 
         var setClauses = new List<DbModificationClause>(); 
         var table = (EntityType)deleteCommand.Target.VariableType.EdmType; 
         if (table.Properties.Any(p => p.Name == column)) 
         { 
          setClauses.Add(DbExpressionBuilder.SetClause(
            DbExpressionBuilder.Property(
             DbExpressionBuilder.Variable(deleteCommand.Target.VariableType, deleteCommand.Target.VariableName), 
             column), 
            DbExpression.FromBoolean(true))); 
         } 

         var update = new DbUpdateCommandTree(
          deleteCommand.MetadataWorkspace, 
          deleteCommand.DataSpace, 
          deleteCommand.Target, 
          deleteCommand.Predicate, 
          setClauses.AsReadOnly(), 
          null); 

         interceptionContext.Result = update; 
        } 
       } 
      } 
     } 
    } 
} 

IdentityConfig.cs

public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext> 
{ 
    protected override void Seed(ApplicationDbContext context) 
    { 
     InitializeIdentityForEF(context); 
     base.Seed(context); 
    } 

    //Create [email protected] with [email protected] in the Admin role   
    public static void InitializeIdentityForEF(ApplicationDbContext db) 
    { 
     //Initialize users and roles... 
    } 
} 

cevap

7

:

protected new void OnModelCreating(DbModelBuilder modelBuilder) {...} 

Sen "yeni" yerine OnModelCreating asla çalıştırılmaz böylece "geçersiz kılma" nin kullanıyorsunuz (bunu kontrol etmek bir kesme noktası eklemek için deneyin). Yani AttributeToTableAnnotationConvention asla çalışmaz ve varlık ek açıklama asla eklenmez.

protected override void OnModelCreating(DbModelBuilder modelBuilder) {...} 

bunu değiştirme Senin yardımın

+0

Geçersiz kılınırsa, orijinal OnModelCreating çağrılmaz ve bu durum böyle olmamalıdır. Diğer taraftan 'yeni' her iki yöntemi de çağırıyor. – nest

+0

Bu doğru değil. Varsayılan yöntemi (gerekirse) atamak için base.OnModelCreating yöntemini geçersiz kılmalı ve çağırmalısınız. Sadece mevcut yöntemde bir kesme noktası ayarlayın ve durup durmadığını test edin, görmeyeceksiniz. – tede24

+0

@ tede24 haklı! –

1

Eh, kod iyi gibi geliyor bana. Belki de uygulamanızı bozan küçük bir hata var. Bu deneyebilirsiniz:

  1. SoftDeleteAttribute

  2. BC_Instance gelen düzenle ApplicationDbConfiguration sınıf

  3. Düzenleme içeriği en yapıcı Sil

    AttributeToTableAnnotationConvention<SoftDeleteAttribute, string> conv = 
        new AttributeToTableAnnotationConvention<SoftDeleteAttribute, string>(
         "SoftDeleteColumnName", 
         (type, attributes) => attributes.Single().ColumnName); 
    
    modelBuilder.Conventions.Add(conv); 
    //this will dynamically add the attribute to all models 
    modelBuilder.Types().Configure(delegate(ConventionTypeConfiguration i) 
    { 
        i.HasTableAnnotation("SoftDeleteColumnName", Entity.G etSoftDeleteColumnName()); 
    }); 
    
  4. OnModelCreating yöntemini kaldırma

    public ApplicationDbContext() 
        : base("DefaultConnection", throwIfV1Schema: false) 
    { 
        DbInterception.Add(new SoftDeleteInterceptor()); 
    } 
    

Bu yardımcı olur umarız! ApplicationDbContext.cs bir hata vardır

+0

Teşekkür çalışması yapacaktır. Bir problem: 'i.HasTableAnnotation ("SoftDeleteColumnName", Entity.GetSoftDeleteColumnName()); -> ''Varlık, geçerli bağlamda mevcut değil'. – nest

+0

Ayrıca, çalışıp çalışmadığını kontrol etmeliyim. Veritabanını doğrudan sorgularsam, deleter kayıtlarını doğru görmeliyim? Önleme sadece koda uygulanır mı? – nest

+0

Benim durumumda, Varlık, –