2017-07-14 71 views
1

嗨! 我有Entity Framework Core 2.xx ORM解決方案,並且模型中的所有對象都創建了(UTC創建時間的時間戳 - 從未更新)和修改字段(實體更新時總是更新)。 我爲這個非常常見的問題閱讀了一些建議實現,它看起來像框架還不能很好地支持它,因爲沒有好的方法來做到這一點,而沒有爲每個實體分別定義映射。 我發現的一個解決方法是定義一個非映射超類,然後手動生成值生成步驟。因爲數據庫UTCDatetime是數據庫端功能,我還必須手動定義我在數據庫中使用utc datetime函數。我知道該怎麼做,在模型生成像這樣流暢的API:使用併發令牌的實體框架核心修改和創建字段

//這個例子中缺少的是什麼DB調用的定義:

modelBuilder.Entity<MyObject>() 
     .Property(p => p.Timestamp) 
     .ValueGeneratedOnAddOrUpdate() 
     .IsConcurrencyToken(); 

,我可以在遷移像加UTC時間代這個:

AddColumn("MyObject", "Created", n => n.DateTime(nullable: false, defaultValueSql: "GETUTCDATE()"));` 

但我的問題是:如果我自動使用MyBaseObject超類自動執行所有操作,我該怎麼辦? (它有這些修改和創建的字段,並沒有自己映射)。我這樣做,現在這樣的,但我不知道如何定義後臺創建現場呼叫「GETUTCDATE()」

if (entityType.ClrType.IsSubclassOf(typeof(MyBaseObject))) 
{ 
        var guidProperty = entityType.FindProperty(nameof(MyBaseObject.GUID)); 
        var createdProperty = entityType.FindProperty(nameof(MyBaseObject.Created)); 
        var modifiedProperty = entityType.FindProperty(nameof(MyBaseObject.Modified)); 

        entityType.AddKey(guidProperty); 
        entityType.SetPrimaryKey(guidProperty);      
        guidProperty.ValueGenerated = ValueGenerated.OnAdd; 


        modifiedProperty.ValueGenerated = ValueGenerated.OnAddOrUpdate; 
        modifiedProperty.IsReadOnlyBeforeSave = true; 
        //modifiedProperty.SetValueGeneratorFactory(); 

        createdProperty.ValueGenerated = ValueGenerated.OnAdd; 
        createdProperty.IsReadOnlyBeforeSave = true; 

        entityType.AddProperty("GUID", typeof(Guid)); 
        entityType.AddProperty("Created", typeof(DateTime)); 
        entityType.AddProperty("Modified", typeof(DateTime)); 
        entityType.AddIndex(modifiedProperty); 
        entityType.AddIndex(createdProperty); 
} 

回答

3

我建議創建一個受限的泛型方法或類,並使用內部的正常流暢的API配置通用屬性。

例如,泛型類的構造函數接收ModelBuilder

class MyBaseObjectConfiguration<TEntity> where TEntity : MyBaseObject 
{ 
    public MyBaseObjectConfiguration(ModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<TEntity>() 
      .HasKey(e => e.GUID); 

     modelBuilder.Entity<TEntity>() 
      .Property(e => e.GUID) 
      .ValueGeneratedNever(); 

     modelBuilder.Entity<TEntity>() 
      .Property(e => e.Created) 
      .ValueGeneratedOnAdd() 
      .HasDefaultValueSql("GETUTCDATE()"); 

     modelBuilder.Entity<TEntity>() 
      .Property(e => e.Modified) 
      .ValueGeneratedOnAddOrUpdate() 
      .HasDefaultValueSql("GETUTCDATE()") 
      .IsConcurrencyToken(); 
    } 
} 

,並用反射調用它裏面OnModelCreating

foreach (var type in modelBuilder.Model.GetEntityTypes().Where(t => t.ClrType.IsSubclassOf(typeof(MyBaseObject)))) 
    Activator.CreateInstance(typeof(MyBaseObjectConfiguration<>).MakeGenericType(type.ClrType), modelBuilder); 
+0

謝謝你 - 這實際上是什麼,我找到理想! – kamakaze