EF с ролью приложения SQL-сервера - PullRequest
3 голосов
/ 17 ноября 2011

Мне нужно использовать правила безопасности приложений на сервере SQL.И я хочу использовать код Enity Framework First.

После успешного входа в систему мое соединение настроено на роль приложения.Затем я создаю свой DbContext, используя это соединение.

Но: EF ожидает закрытый объект соединения.И закрытие соединения прекращает роль приложения.

Как я могу решить эту дилемму?

Ответы [ 3 ]

6 голосов
/ 18 ноября 2011

Мне удалось получить эту работу в два этапа:

Отключить пул подключений, который постоянно упоминается для подключений с использованием ролей приложений.Поскольку у меня есть настольное приложение, для меня это не проблема.

Добавьте обработчик к DbConnection.StateChanged и активируйте роль приложения при каждом открытии соединения.Без пула соединений нет необходимости sp_unsetapprole при закрытии.Так что это работает для меня:

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

Полагаю, если для кого-то необходим пул, она может позвонить sp_unsetapprole при закрытии соединения в этом же обработчике.

4 голосов
/ 24 августа 2012

Поскольку этот вопрос стоит на первом месте в списке результатов поиска, я просто хотел добавить слово предостережения. У меня есть приложение, которое должно было использовать роль приложения, и решение okrumnow сначала показалось работающим.

Однако в модульном тестировании я обнаружил, что иногда обработка события StateChanged приводит к тому, что событие будет вызвано дважды, и вы получите ошибку:

«Олицетворение контекста безопасности сеанса» не может быть вызвано в этом пакете, потому что его вызвал одновременный пакет.

Кажется, это помогает изменить условное выражение на:

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

Но это по-прежнему не устраняет ошибку. Я подтвердил это в EF4.3 и EF5. Ladislav правильно, что идеальным способом является создание соединения для DbContext и сообщение контексту, что он не является владельцем.

Кроме того, при такой настройке пул соединений невозможен, поскольку нет события ConnectionState.Closing, по которому вы могли бы позвонить sp_unsetapprole до закрытия вашего соединения.

Поскольку у меня была гибкость, мое решение состояло в том, чтобы исключить использование роли приложения и вместо этого использовать выделенный вход в SQL. В любом случае вы жестко кодируете пароль ...

0 голосов
/ 17 ноября 2011

EF не имеет встроенной поддержки для этого.Я думаю, что обходной путь может быть:

  • Создание собственного соединения и передача его (закрытое) в контекст EF / EntityConnection.Это должно гарантировать, что у вас будет время жизни соединения под вашим контролем, и EF не закроет его (но я уже видел жалобы, что он не работает с DbContext).
  • Как только у вас есть экземпляр контекста, созданный set applicationроль.Сам контекст не должен генерировать какие-либо запросы к базе данных (за исключением DbContext с кодом, который сначала проверяет версию базы данных), поэтому установка роли после создания контекста не должна вызывать никаких проблем.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...