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

时间:2010-10-14 06:06:38

标签: nhibernate entity-framework stored-procedures entity-framework-4 objectcontext

每次查询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
    }
}

上面的意思是我可以在我的测试中编写代码,并且everthing是绿色的(YAY!)但是然后我的同事在他的业务逻辑中的某个地方使用了TestMethod2中的代码而且它们全都搞定了 - 没有人知道在哪里以及为什么所有测试都是绿色的:/

[EDIT2]

This blog post肯定没有回答我的问题,但实际上解决了我的问题。也许与NHibernate合作将更适合我的目的:)

2 个答案:

答案 0 :(得分:1)

我们已经使用过这种模式。

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

答案 1 :(得分:0)

最后我找到了答案。我可以使用EFProviderWrappers中的EFProvider wraper工具包来包装连接。 为此,我主要必须从EFProviderWrapperConnection派生并覆盖DbConnection.Open()方法。我已经尝试使用跟踪提供程序,它工作正常。一旦我用我的解决方案测试它,我将添加更多信息。