针对多个插入的LINQ DataContext持久性最佳实践

针对多个插入的LINQ DataContext持久性最佳实践,linq,linq-to-sql,optimization,Linq,Linq To Sql,Optimization,我有一个logger类,在我的应用程序中,无论是在请求还是线程中,都可以使用它。记录器由每个Log.insert(字符串文本)的数据库插入组成。记录器是一个静态类,为每个要插入的调用创建一个新的数据库上下文。可能有许多要插入的调用,同时大量数据库上下文不利于优化。(我有时会遇到数据库超时,因为应用程序中的sql操作太多,所以确实需要优化) 是否可以通过在Logger类的静态成员中创建和存储单个数据库上下文(仅用于Log.Inserts)来优化这一点?还是会失败 记录器类的简化版本 [Table]

我有一个logger类,在我的应用程序中,无论是在请求还是线程中,都可以使用它。记录器由每个Log.insert(字符串文本)的数据库插入组成。记录器是一个静态类,为每个要插入的调用创建一个新的数据库上下文。可能有许多要插入的调用,同时大量数据库上下文不利于优化。(我有时会遇到数据库超时,因为应用程序中的sql操作太多,所以确实需要优化)

是否可以通过在Logger类的静态成员中创建和存储单个数据库上下文(仅用于Log.Inserts)来优化这一点?还是会失败

记录器类的简化版本

[Table]
public class Log
{
   [Column]
   public string Text { get; set; }

   private static DataContext DatabaseContextInsert { get; set; }

   public static void Insert(string text)
   {
      if (DatabaseContextInsert == null)
      {
          DatabaseContextInsert = DataContextHelper.GetDataContext();            
      }

      var log = new Log { Text = text };          

      lock (DatabaseContextInsert)
      {
        DatabaseContextInsert.GetTable<Log>().InsertOnSubmit(log);
        DatabaseContextInsert.SubmitChanges();
      }
   }
}
[表格]
公共类日志
{
[专栏]
公共字符串文本{get;set;}
私有静态DataContext DatabaseContextInsert{get;set;}
公共静态空白插入(字符串文本)
{
如果(DatabaseContextInsert==null)
{
DatabaseContextInsert=DataContextHelper.GetDataContext();
}
var log=新日志{Text=Text};
锁(DatabaseContextInsert)
{
DatabaseContextInsert.GetTable().InsertOnSubmit(日志);
DatabaseContextInsert.SubmitChanges();
}
}
}

使用静态记录器将是一个非常糟糕的主意。除了同步问题之外,您还可能会遇到数据上下文中永久保存的所有项的问题(数据上下文喜欢保存它所看到的对象)

您提到,您认为大量的数据上下文不利于优化,但连接可能已经是池化的(默认情况下是这样的),因此数据上下文实际上不是很“重”

如果日志条目不需要同步插入,我会尝试做一些事情,比如将新的日志项抛出到队列中(同步访问),并让一个工作线程每10秒清空一次队列,基本上是这样做的:

// adding an item
lock(queue) { queue.Enqueue(text); }


// worker code, every 10 seconds
List<string> items = new List<string>();
lock(queue) {
    while(queue.Count != 0) items.Add(items.Dequeue);
}
using(var ctx = CreateContext()) {
    foreach(var text in items) {
        ctx.Logs.InsertOnSubmit(new Log { Text = text });
    }
    ctx.SubmitChanges();
}

它完全不需要数据上下文,更简单,也不需要考虑事务。

是否要显示一些代码?我认为这将有助于您[[1]:保存日志条目非常重要-因此具有延迟的线程不是完美的解决方案(需要跟踪为什么在示例中应用程序会融化,这可能会阻止线程完成)。但是简单的SQL add可能是一个很好的解决方案,不需要跟踪添加的对象,因为它们较新的对象将被更改。但是有没有一种简单的LINQ到SQL方法来创建这个简单的插入?我有比“文本”更多的字段,因此最好使用对象而不是SQL字符串进行插入。
using(var conn = CreateOpenConnection()) {
    conn.Execute("insert [Log]([Text]) values(@text)", new {text});
}