每次查询我的 ObjectContext 之前,我都需要执行一个 SQL 存储过程。我想要实现的是将 设置CONTEXT_INFO
为稍后将与我的大多数查询一起使用的值。
有没有人这样做过?那可能吗?
[编辑]
目前,我通过打开连接并在我的 ObjectContext 构造函数中执行存储过程来实现这一点,如下所示:
public partial class MyEntitiesContext
{
public MyEntitiesContext(int contextInfo) : this()
{
if (Connection.State != ConnectionState.Open)
{
Connection.Open(); // open connection if not already open
}
var connection = ((EntityConnection)Connection).StoreConnection;
using (var cmd = connection.CreateCommand())
{
// run stored procedure to set ContextInfo to contextInfo
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "[dbo].[SetContextInfo]";
cmd.Parameters.Add(new SqlParameter("@ci", _contextInfo));
cmd.ExecuteNonQuery();
}
// leave the connection open to reuse later
}
}
然后在我的集成测试中:
[TestMethod]
public void TestMethod1()
{
using (var ctx = new MyEntitiesContext(1))
{
Assert.AreEqual(2, ctx.Roles.ToList().Count);
Assert.AreEqual(2, ctx.Users.ToList().Count);
}
}
但这需要我保持连接打开 - 这很容易出错,因为我总是需要 CONTEXT_INFO,而另一个开发人员可能很容易做到:
[TestMethod]
public void TestMethod2()
{
using (var ctx = new MyEntitiesContext(1))
{
// do something here
// ... more here :)
ctx.Connection.Close(); // then out of the blue comes Close();
// do something here
Assert.AreEqual(2, ctx.Roles.ToList().Count);
Assert.AreEqual(2, ctx.Users.ToList().Count); // this fails since the where
// clause will be:
// WHERE ColumnX = CAST(CAST(CONTEXT_INFO() AS BINARY(4)) AS INT)
// and CONTEXT_INFO is empty - there are no users with ColumnX set to 0
// while there are 2 users with it set to 1 so this test should pass
}
}
以上意味着我可以像在我的测试中那样编写代码,并且一切都是绿色的(耶!)但是我的同事在他的业务逻辑的某个地方使用了来自 TestMethod2 的代码,这一切都搞砸了——而且没人知道在哪里以及为什么所有测试都是绿色的:/
[编辑2]
这篇博文当然没有回答我的问题,但实际上解决了我的问题。也许使用 NHibernate 会更适合我的目的:)