客户需要将每个数据更改与进行修改的实际用户一起记录到日志表中。应用程序使用一个 SQL 用户访问数据库,但我们需要记录“真实”用户 ID。
我们可以在 t-sql 中通过为每个表插入和更新编写触发器,并使用 context_info 来存储用户 ID 来做到这一点。我们将用户 ID 传递给存储过程,将用户 ID 存储在 contextinfo 中,触发器可以使用此信息将日志行写入日志表。
我找不到使用 EF 做类似事情的地方或方式。所以主要目标是:如果我通过 EF 对数据进行更改,我想以半自动方式将确切的数据更改记录到表中(所以我不想在之前检查每个字段的更改保存对象)。我们正在使用 EntitySQL。
不幸的是,我们必须坚持使用 SQL 2000,因此 SQL2008 中引入的数据更改捕获不是一种选择(但也许这对我们来说也不是正确的方法)。
任何想法、链接或起点?
[编辑] 一些注意事项:通过使用 ObjectContext.SavingChanges 事件处理程序,我可以获得可以注入 SQL 语句来初始化 contextinfo 的点。但是我不能混合使用 EF 和标准 SQL。所以我可以获得 EntityConnection 但我无法使用它执行 T-SQL 语句。或者我可以获取EntityConnection的连接字符串,并基于它创建一个SqlConnection,但是会是不同的连接,所以contextinfo不会影响EF进行的保存。
我在 SavingChanges 处理程序中尝试了以下操作:
testEntities te = (testEntities)sender;
DbConnection dc = te.Connection;
DbCommand dcc = dc.CreateCommand();
dcc.CommandType = CommandType.StoredProcedure;
DbParameter dp = new EntityParameter();
dp.ParameterName = "userid";
dp.Value = textBox1.Text;
dcc.CommandText = "userinit";
dcc.Parameters.Add(dp);
dcc.ExecuteNonQuery();
错误:EntityCommand.CommandText 的值对于 StoredProcedure 命令无效。与 SqlParameter 而不是 EntityParameter 相同:不能使用 SqlParameter。
StringBuilder cStr = new StringBuilder("declare @tx char(50); set @tx='");
cStr.Append(textBox1.Text);
cStr.Append("'; declare @m binary(128); set @m = cast(@tx as binary(128)); set context_info @m;");
testEntities te = (testEntities)sender;
DbConnection dc = te.Connection;
DbCommand dcc = dc.CreateCommand();
dcc.CommandType = CommandType.Text;
dcc.CommandText = cStr.ToString();
dcc.ExecuteNonQuery();
错误:查询语法无效。
所以我在这里,坚持在 Entity Framework 和 ADO.NET 之间建立一座桥梁。如果我能让它工作,我会发布一个概念证明。