2015-06-16 26 views
2

記錄插入/更新的習慣是什麼?LINQ:透明記錄的插入和更新

我在MS SQL Server數據庫日誌表,和C#類(例如簡化)

[Table(Name = "dbo.Sys_Log")] 
public class Sys_Log 
{ 
    // Read-only, db-generated primary key ID 
    private int _logID; 
    [Column(IsPrimaryKey=true, Storage="_logID", IsDbGenerated=true)] 
    public int logID 
    { 
     get 
     { 
      return this._logID; 
     } 
    } 

    // Read-only db-generated datetime field 
    private System.DateTime _logTime; 
    [Column(Storage="_logTime", IsDbGenerated=true)] 
    public System.DateTime logTime 
    { 
     get 
     { 
      return this._logTime; 
     } 
    } 

    // Read-write string field 
    private string _logEvent; 
    [Column(Storage="_logEvent")] 
    public string logEvent 
    { 
     get 
     { 
      return this._logEvent; 
     } 
     set 
     { 
      this._logEvent = value; 
     } 
    } 

    public Sys_Log() {} 

    public Sys_Log(string logEvent) 
    { 
     this.logEvent = logEvent; 
    } 
} 

而且我這是怎麼添加日誌條目:

Table<Sys_Log> linqLog = db.GetTable<Sys_Log>(); 
Sys_Log l = new Sys_Log("event"); 
linqLog.InsertOnSubmit(l); 
db.SubmitChanges(); 

我我對這段代碼並不特別滿意。我想這樣的事情,而不是:

Sys_Log.Log("event"); 

我知道如何可以做到這一點,但我想知道如果我下面LINQ的理念。有了這個代碼添加到Sys_Log類

private static DataContext db; 
public static void Connect(DataContext db) 
{ 
    Sys_Log.db = db; 
} 
public static void Log(string logEvent) 
{ 
    Table<Sys_Log> linqLog = db.GetTable<Sys_Log>(); 
    Sys_Log l = new Sys_Log(logEvent); 
    linqLog.InsertOnSubmit(l); 
    db.SubmitChanges(); 
} 

我現在可以這樣做:

Sys_Log.Connect(db); // Only once, at init 
Sys_Log.Log("event1"); 
Sys_Log.Log("event2"); 

是否有任何陷阱,其實除了數據庫更新幾次,這可能被認爲是無效的?

**************更新******************

繼@usr的建議不重用DataContext對象,我已對Sys_Log類進行了這些更改:

private static SqlConnection db; 
public static void Connect(SqlConnection db) 
{ 
    Sys_Log.db = db; 
} 
public static void Log(string logEvent) 
{ 
    DataContext ctx = new DataContext(db); 
    ctx.CommandTimeout = 240; 

    Table<Sys_Log> linqLog = ctx.GetTable<Sys_Log>(); 
    Sys_Log l = new Sys_Log(logEvent); 
    linqLog.InsertOnSubmit(l); 
    ctx.SubmitChanges(); 
} 

回答

1

每次都使用新的數據上下文。重複使用相同的背景下具有災難性的後果:

  1. 沒有實體內存有史以來發布
  2. 當一個無效的實體進入上下文(由於錯誤)被卡住,並會永遠阻止的SubmitChanges得手。應用程序將永遠不會恢復

另請注意,L2S已棄用且EF已取代它。

如果你真的想要,你可以共享一個SqlConnection並長期使用它。這就需要通過處理斷開的連接。由於連接池的存在,幾乎沒有性能激勵措施可以做到這一點。

它通常是最簡單和最清晰的方式來使用丟棄連接。例如:注入工廠:

Func<SqlConnection> myFactory =() => new SqlConnection(myConnStr); 

這就是它的全部。使用它,一如既往,與using

using(var conn = myFactory()) { ... } 
+0

謝謝,我已經將您的建議納入我的文章。我會注意到你對EF取代L2S的評論,但是由於項目的其餘部分正在使用L2S,此時我將堅持使用L2S。 – Passiday

+0

這是合理的。我現在有100kLOC卡在L2S上,因爲在LINQ翻譯時,EF仍然達不到標準。 – usr

+0

哦,看着那個代碼,你不應該重複使用SqlConnection。它可以打破永久性渲染應用程序。注入連接工廠,可能是'Func '。 – usr