执行记录插入/更新的自定义文是什么?
我在MS SQL服务器数据库中有这个日志表,还有一个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();
}
每次都使用新的数据上下文。重用相同的上下文会带来灾难性的后果:
- 不会释放任何实体内存
- 当无效实体进入上下文(由于错误)时,它将被卡住,并将永远阻止 SubmitChanges 成功。应用程序将永远无法恢复
另请注意,L2S 已弃用,EF 已取代它。
如果您确实愿意,您可以共享 SqlConnection 并长期使用它。这需要您处理断开的连接。由于连接池,这样做几乎没有性能激励。
这通常是使用一次性连接的最简单、最清晰的方法。注入工厂,例如:
Func<SqlConnection> myFactory = () => new SqlConnection(myConnStr);
仅此而已。与往常一样,使用它与using
一起使用:
using(var conn = myFactory()) { ... }