Nhibernate 在EntityFramework生成的每个查询之前执行SQL存储过程

Nhibernate 在EntityFramework生成的每个查询之前执行SQL存储过程,nhibernate,entity-framework,stored-procedures,entity-framework-4,objectcontext,Nhibernate,Entity Framework,Stored Procedures,Entity Framework 4,Objectcontext,每次查询ObjectContext之前,我都需要执行一个SQL存储过程。我想要实现的是将上下文\u INFO设置为一个值,该值稍后将用于我的大多数查询 有人这样做过吗?可能吗 [编辑] 目前,我通过打开连接并在ObjectContext构造函数中执行存储过程来实现这一点,如下所示: public partial class MyEntitiesContext { public MyEntitiesContext(int contextInfo) : this() {

每次查询ObjectContext之前,我都需要执行一个SQL存储过程。我想要实现的是将
上下文\u 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);
    }
}
但这需要我保持连接打开-这很容易出错,因为我总是需要上下文信息,而其他开发人员可能很容易做到:

[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中的代码,并且它都是f'd的-没有人知道在哪里以及为什么,因为所有的测试都是绿色的:/

[EDIT2]


当然没有回答我的问题,但实际上解决了我的问题。也许使用NHibernate更适合我的目的:)

我们使用了这种模式


但是我们这样做的方式是调用存储过程作为每个db上下文中的第一个操作

我终于找到了答案。我可以使用中的EFProvider wraper工具包包装连接。
为此,我主要必须从
EFProviderWrapperConnection
派生并重写
DbConnection.Open()
方法。我已经在跟踪提供者那里试过了,效果很好。一旦我用我的解决方案对其进行了测试,我将添加更多信息。

谢谢-我想要它的目的是在多租户应用程序中过滤租户数据。我不想将TenantId传递给每个存储过程,而是使用依赖于上下文信息的视图,因此我希望在查询数据库之前始终设置上下文信息。我还是想用EF。我从一篇很棒的博客文章中得到了这个想法:这有点容易出错——也许可以通过AOP(比如PostSharp)很好地实现,但我还是不想这样做。实际上,我可以编写自己的ADO.NET提供程序来包装SqlClient,并且总是在提供DbConnection之前先执行存储过程,然后返回连接。但是我不知道这在SqlClient的架构中是否可行。我们将调用存储过程的代码放在它自己的方法中,然后我们可以进行计数并检查调用它的次数与使用db上下文的次数是否匹配。好主意。仍然有人可以调用ctx.Connection.Close();而且你的ctx使用和方法调用计数测试毫无价值。。