實體框架7審核日誌


我正在將一個舊項目移植到ASP.NET 5和Entity Framework 7.我使用數據庫第一種方法(DNX scaffold)來創建模型。

舊項目基於實體框架4,審計跟踪是通過覆蓋DbContextSaveChanges方法實現的:

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);
}

我的問題是,我如何在Entity Framework 7中實現它?我必須採用代碼第一種方法嗎?

熱門答案

基本上你有兩種方法來實現這個目標:

使用ChangeTracker API(EF 6+):

這是我們目前在EF 6中的方式,它仍然有效並適用於EF 7:

首先,您必須確保您的實體正在為審計字段實現公共接口:

public interface IAuditableEntity 
{
    int? CreatedById { get; set; }

    DateTime Created { get; set; }

    int? ModifiedById { get; set; }

    DateTime Modified { get; set; }
}


然後,您可以覆蓋SaveChanges並使用審計值更新每個公共字段:

public interface IAuditableEntity 
{
    int? CreatedById { get; set; }

    DateTime Created { get; set; }

    int? ModifiedById { get; set; }

    DateTime Modified { get; set; }
}


使用EF 7新的“陰影屬性”功能:

陰影屬性是實體類中不存在的屬性。這些屬性的值和狀態僅在Change Tracker中維護。

換句話說,審核列不會在您的實體上公開,與上面的實體相比,它們似乎是一個更好的選擇。

要實現陰影屬性,首先必須在實體上配置它們。比方說,你有一個需要有一些審計列的User對象:

public interface IAuditableEntity 
{
    int? CreatedById { get; set; }

    DateTime Created { get; set; }

    int? ModifiedById { get; set; }

    DateTime Modified { get; set; }
}


配置完成後,您現在可以在SaveChanges()覆蓋上訪問它們並相應地更新它們的值:

public interface IAuditableEntity 
{
    int? CreatedById { get; set; }

    DateTime Created { get; set; }

    int? ModifiedById { get; set; }

    DateTime Modified { get; set; }
}


最後的想法:

為了實現像審計列這樣的東西,我將採用Shadow Properties方法,因為這些是交叉關注的問題,並不一定屬於我的域對象,因此以這種方式實現它們將使我的域對象保持良好和乾淨。





許可下: CC-BY-SA
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因