2015-04-06 40 views
1

我想實現nlog到每個動作添加一個元素。 所以當我做myContext.Society.Add()時,我想記錄一些東西。 我創建了一個類DbSetExtension並修改了上下文StockContext以使用DbSetExtension<T>代替DbSet在實體框架中繼承DbSet <TEntity>代碼優先NullReference

public class DbSetExtension<T> : DbSet<T> where T : class 
{ 
    public override T Add(T entity) 
    { 
     LoggerInit.Current().Trace("Add Done"); 
     return base.Add(entity); 
    } 
} 

當我啓動程序時,我注意到當我訪問myContext.Society.Add時。 社會爲空。所以我想我錯過了我的課DbSetExtension但我沒有找到。

public class StockContext : DbContext 
{ 

    public StockContext() 
     : base("StockContext") 
    { 
    } 

    public DbSet<HistoricalDatas> HistoricalDatas { get; set; } 
    public DbSet<Society> Society { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();   
    } 
} 

你有什麼想法, 問候, 亞歷

[更新] 代碼允許添加。 如果我用DbSet替換DbSetExtension,則相同的代碼有效。 所以我的假設是我錯過了一些東西,當我從DbSet繼承。

public bool SetSymbols() 
    {    
     CsvTools csvThreat = new CsvTools(); 
     List<Eoddata> currentEnum = 
      csvThreat.ExtractData<Eoddata>(ConfigurationManager.GetString("FilePathQuotes", "")); 
     currentEnum.ForEach(
      c => 
       { 
        //LoggerInit.Current().Trace("Add Done"); 
        Sc.Society.Add(
         new Society() 
         { 
          RealName = c.Description, 
          Symbol = String.Format("{0}.PA", c.Symbol), 
          IsFind = !String.IsNullOrEmpty(c.Description) 
         }); 
       });    
     if (Sc.SaveChanges() > 0) 
      return true; 
     return false; 
    } 
+0

可以大家分享的這部分內容代碼:'myContext.Society.Add.' – renakre 2015-04-06 14:39:34

+0

我添加了關於動作添加的代碼? – user2416437 2015-04-06 20:24:02

+0

我添加了添加動作的代碼。 – user2416437 2015-04-06 20:24:18

回答

1

在我看來,你採取了完全錯誤的方向。 DbContext使DbSet而不是DbSetExtension類。它能夠實例化DbSet類型的對象,而不是你自己的類型。這基本上是你爲什麼得到這個例外。對其進行修復需要對EF內部進行攻擊,我擔心這個問題只是您的一個開始。相反,我會建議你使用攔截器類使用EF記錄的一般方法。這在文章Logging and Intercepting Database Operations的末尾有詳細解釋。通常這種方法對你來說會更有利。爲什麼?因爲DbContext只是與db溝通的中間人。在日誌中,您通常關心數據庫及其數據會發生什麼情況。如果不調用SaveChanges,則在DbSet上調用Add方法可能根本沒有任何效果。相反的查詢攔截器讓你嚴格只記錄與db的交互。根據發送給db的查詢,你可以區分發生了什麼。

但是,如果你instist你的方法,我將使用擴展方法,而不是從DbSet派生建議您:

public static class DbSetExtensions 
{ 
    public static T LoggingAdd<T>(this DbSet<T> dbSet, T entity) 
    { 
     LoggerInit.Current().Trace("Add Done"); 
     return dbSet.Add(entity); 
    } 
} 

,並調用它像這樣:

context.Stock.LoggingAdd(entity); 
+0

嗨mr100,謝謝你的回答。您的建議符合我的需求,因此我實現了「記錄和攔截數據庫操作」。此外,您關於擴展的示例也是正確的。非常感謝,我認爲我的方式是錯誤的。 – user2416437 2015-04-07 20:54:24