2016-01-03 22 views
6

Eski bir projeyi ASP.NET 5 ve Entity Framework 7'ye taşıyorum. Modeli oluşturmak için veritabanını ilk yaklaşım (DNX scaffold) kullandım. Entity Framework 7 denetim günlüğü

eski proje

İdare Framework 4 dayalıdır ve denetim izleme DbContext ait SaveChanges yöntemini geçersiz kılarak uygulanır:

public override int SaveChanges(System.Data.Objects.SaveOptions options) 
{ 
    int? UserId = null; 
    if (System.Web.HttpContext.Current != null) 
     UserId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault(); 

    foreach (ObjectStateEntry entry in ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified)) 
    { 
     Type EntityType = entry.Entity.GetType(); 

     PropertyInfo pCreated = EntityType.GetProperty("Created"); 
     PropertyInfo pCreatedById = EntityType.GetProperty("CreatedById"); 
     PropertyInfo pModified = EntityType.GetProperty("Modified"); 
     PropertyInfo pModifiedById = EntityType.GetProperty("ModifiedById"); 

     if (entry.State == EntityState.Added) 
     { 
      if (pCreated != null) 
       pCreated.SetValue(entry.Entity, DateTime.Now, new object[0]); 
      if (pCreatedById != null && UserId != null) 
       pCreatedById.SetValue(entry.Entity, UserId, new object[0]); 
     } 
     if (pModified != null) 
      pModified.SetValue(entry.Entity, DateTime.Now, new object[0]); 
     if (pModifiedById != null && UserId != null) 
      pModifiedById.SetValue(entry.Entity, UserId, new object[0]); 
     } 
    } 

    return base.SaveChanges(options); 
} 

Sorum, nasıl Entity Framework 7'de bu uygulayabilirsiniz nedir? İlk yaklaşımı benim almalı mıyım? Bu şu anda EF 6'da bunu yoludur

ve hala öyle:

ChangeTracker API kullanarak (EF 6+):

+0

EF7 bitmiş ve üretime hazır değil. İlk önce EF6 ve DbContext API'ye giderdim. EF7 bekleme listesinde hala yeterince olgunlaşmadan önce uygulanması gereken birçok öğe var. –

+0

Anlayışım, onu aynı şekilde ... veya temelde aynı şekilde uygulayabilmenizdir. – Seabizkit

+0

Şahsen, veriyi ilgili katmanda System.Web'e başvurmak yerine, kullanıcı kimliğini bir yönteme iletmelisiniz. – Seabizkit

cevap

5

Temel olarak iki Bunu başarmak için yollar var geçerli ve EF 7 için çalışan:

:

Öncelikle varlıkları denetim alanları için ortak bir arayüz uygulamaktadır emin olmalıyız


Sonra denetim değerlerle her ortak alan SaveChanges geçersiz kılmak ve güncelleyebilirsiniz:

public override int SaveChanges() 
{ 
    int? userId = null; 
    if (System.Web.HttpContext.Current != null) 
     userId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault(); 

    var modifiedEntries = ChangeTracker.Entries<IAuditableEntity>() 
      .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified); 

    foreach (EntityEntry<IAuditableEntity> entry in modifiedEntries) 
    { 
     entry.Entity.ModifiedById = UserId; 
     entry.Entity.Modified = DateTime.Now; 

     if (entry.State == EntityState.Added) 
     { 
      entry.Entity.CreatedById = UserId; 
      entry.Entity.Created = DateTime.Now; 
     } 
    } 

    return base.SaveChanges(); 
} 


EF kullanma 7 yeni "Gölge Özellikleri" Özelliği:

Shadow properties vardır varlık sınıfınızda bulunmayan özellikler. Bu özelliklerin değeri ve durumu yalnızca İzleme Değiştiricide tutulur. Başka bir deyişle, denetim sütunları sizin varlıklarınız üzerinde bulunmadığınız bir yere kıyasla daha iyi bir seçenek gibi görünen varlıklar üzerinde görünmeyecektir.

Gölge özelliklerini uygulamak için önce bunları varlıklarınızda yapılandırmanız gerekir.

kez yapılandırılmış
protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<User>().Property<int>("CreatedById"); 

    modelBuilder.Entity<User>().Property<DateTime>("Created"); 

    modelBuilder.Entity<User>().Property<int>("ModifiedById"); 

    modelBuilder.Entity<User>().Property<DateTime>("Modified"); 
} 


, şimdi SaveChanges() geçersiz kılma bunlara erişebilirsiniz ve buna göre onların değerlerini güncellemek:

public override int SaveChanges() 
{ 
    int? userId = null; 
    if (System.Web.HttpContext.Current != null) 
     userId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault(); 

    var modifiedBidEntries = ChangeTracker.Entries<User>() 
     .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified); 

    foreach (EntityEntry<User> entry in modifiedBidEntries) 
    { 
     entry.Property("Modified").CurrentValue = DateTime.UtcNow; 
     entry.Property("ModifiedById").CurrentValue = userId; 

     if (entry.State == EntityState.Added) 
     { 
      entry.Property("Created").CurrentValue = DateTime.UtcNow; 
      entry.Property("CreatedById").CurrentValue = userId; 
     } 
    } 

    return base.SaveChanges(); 
} 
Diyelim ki bazı denetim sütunları olması gerekir bir kullanıcı nesne var örneğin diyelim


Son Düşünceler: denetim kolonlar gibi bir şey uygulamak için

, ben alacağım Gölge Özellikleri yaklaşımı, bunlar kesişen kaygılardır ve etki alanı nesnelerime ait olmaları gerekmez, böylece bu şekilde uygulandıklarında etki alanı nesnelerim güzel ve temiz tutulur.

+0

EF6 API kullanarak silinen ve m-m ilişkisini denetlemede bana yardımcı olabilir misiniz? –

0

Yardımcı olabilecek bir kitaplık üzerinde çalıştım.

Audit.EntityFramework kütüphanesine bir göz atın, SaveChanges() numaralı kesişme noktasını engeller ve EF Çekirdek sürümleriyle uyumludur.