2017-02-21 54 views
0

我有了一個DateTime財產,LastModified,我想使用攔截功能的實體框架,將其值設置6.1實體框架攔截設置和填充自定義值靠背插入後

我已經創建了一個實體類一個EntityFramework攔截器,用於填充插入命令並正確設置INSERT語句中的值。

我的僞代碼看起來像一個生成的ID此

簡單的實體類和LastModified

public class Item { 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int Id{get;set;} 
    public DateTime LastModified{get;set;} 
} 

攔截

public class TestInterceptor : IDbCommandTreeInterceptor 
{ 
    void IDbCommandTreeInterceptor.TreeCreated(DbCommandTreeInterceptionContext interceptionContext) 
    { 
     if (interceptionContext.OriginalResult.DataSpace != DataSpace.SSpace) 
      return; 

     var insertCommand = interceptionContext.Result as DbInsertCommandTree; 
     if (insertCommand != null) 
     { 
      //get setClauses of insert command 
      var setClauses = insertCommand.SetClauses.ToList(); 

      //this index is hardcoded to simplify the example 
      //that we change the value of one of the setClauses to a custom value. 
      var clause = setClauses[0]; 
      clause = DbExpressionBuilder.SetClause(clause.Property(),DbExpression.FromDateTime(DateTime.UtcNow));    
      setClauses[0] = clause; 

      interceptionContext.Result = DbInsertCommandTree(
       insertCommand.MetadataWorkspace, 
       insertCommand.DataSpace, 
       insertCommand.Target, 
       setClauses.AsReadOnly(), 
       insertCommand.Returning); 
     } 

    } 
} 
(其使用DbConfiguration,這裏沒有涉及加)

創建實例對象的代碼

using(var ctx = new MyDbContext()){ 
    var item = new Item(); 
    ctx.Items.Add(item); 
    ctx.SaveChanges(); 
} 

問題是數據庫具有正確的LastModified列值,但item實例沒有。它具有正確設置的ID。我想我需要修改insertCommand.Returning但是如何?

UPDATE: 想澄清,我知道有更簡單的方法可以做到這一點,但這篇文章的目的是爲了使用攔截器,上面的例子是修剪下來的清晰度。最終結果將使用屬性來標記應該受此影響的實體屬性。

回答

0

我有了一個DateTime屬性,上次更改的實體類,我想使用攔截功能的實體框架6.1

將其值設置如果您想設置LastModified屬性值如果你想通過你的數據庫引擎(使用默認或TRIGGER)設置爲LastModified屬性值,你可以標記您正確

var entities = ChangeTracker.Entries().Where(x => x.Entity is Item && (x.State == EntityState.Added || x.State == EntityState.Modified)); 
foreach (var entity in entities) 
{ 
    if (entity.State == EntityState.Added) 
    { 
     ((BaseEntity)entity.Entity).LastModified = DateTime.UtcNow; 
    } 
} 

:在一個地方你的應用程序,你可以調用SaveChanges之前使用ChangeTracker做到這一點() ty與此:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
public DateTime? LastUpdated { get; set; } 

使用IDbCommandTreeInterceptor這種情況看起來像一個過度工程給我。

+0

這解決了特殊的情況,但它不使用的攔截功能。問題的目的是學習如何使用攔截器來做到這一點。我已經更新了原始問題,在這一點上更加清楚。 – Dan

0

你可以使用相當不錯的庫來管理你的攔截器。 EntityHooks

這是例如,你怎麼能輕鬆實現你的目標:

public class MyDbContext : DbContext 
{ 
    public MyDbContext() 
    { 
     this.CreateHook() 
      .OnSave<Item>() 
      .Do(i=> i.LastUpdated = DateTime.Now) 
    } 
} 
+0

這解決了特定情況,但它不使用攔截器功能。問題的目的是學習如何使用攔截器來做到這一點。 – Dan