EF具有SQL服务器应用程序角色

时间:2011-11-17 11:45:11

标签: c# sql-server entity-framework

我需要在sql server上使用应用程序规则安全性。我想先使用Enity Framework Code。

成功登录后,我的连接将设置为应用程序角色。然后我使用此连接创建我的DbContext。

但是:EF期望一个封闭的连接对象。关闭连接会降低应用程序角色。

我如何解决这个难题?

3 个答案:

答案 0 :(得分:6)

我设法通过两个步骤完成了这项工作:

关闭连接池,这是使用应用程序角色的连接一直提到的。由于我有一个桌面应用程序,这对我来说没问题。

DbConnection.StateChanged添加处理程序,并在每次打开连接时激活应用程序角色。如果没有连接池,则关闭时无需sp_unsetapprole。所以这对我有用:

context.Database.Connection.StateChanged += (sender, args) =>
  if (args.CurrentState == ConnectionState.Open) {
    activateAppRole((DbConnection)sender, ...);
  }
}

我想,如果Pooling对某人至关重要,她可以在同一个处理程序中关闭连接时调用sp_unsetapprole

答案 1 :(得分:4)

由于搜索结果列表中的这个问题很高,我只是想提醒一下。我有一个需要使用应用程序角色的应用程序,并且 okrumnow 的解决方案似乎最初起作用。

然而,在单元测试中,我发现有时处理StateChanged事件会导致事件被引发两次,你会得到错误:

  

“模拟会话安全上下文”无法在此批处理中调用,因为同时批处理已调用它。

似乎有助于将条件更改为:

args.CurrentState == ConnectionState.Open &&
    args.CurrentState == ConnectionState.Closed

但它仍然没有消除错误。我在EF4.3和EF5中证实了这一点。 Ladislav 是正确的,理想的方法是为DbContext创建连接并告诉上下文它不拥有它。

此外,此设置永远不可能建立连接池,因为没有ConnectionState.Closing事件,您可以在关闭连接之前致电sp_unsetapprole

由于我具有灵活性,我的解决方案是消除app角色的使用并改为使用专用的SQL登录。无论哪种方式,你都要对密码进行硬编码......

答案 2 :(得分:0)

EF对此没有任何原生支持。我想解决方法可能是:

  • 创建自己的连接并将其传递(关闭)到EF context / EntityConnection。这应该强制您将在您的控制下拥有连接生命周期,并且EF不会关闭它(但我已经看到抱怨它不能用于DbContext)。
  • 创建上下文实例后,设置应用程序角色。上下文本身不应该对数据库生成任何查询(DbContext除了代码首先检查数据库的版本),因此在创建上下文后设置角色不应该导致任何问题。