Для вставки платформы Entify требуется разрешение Select - PullRequest
10 голосов
/ 10 ноября 2009

Мы используем LINQ to Entities для записи записей в базу данных аудита (SQL Server 2008). Поскольку это выделенная база данных аудита, мы только вставляем строки - мы никогда не читаем никаких строк, не обновляем и не удаляем их из приложения аудита.

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

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

Отказано в разрешении SELECT для объекта «AuditEvent», базы данных «IdentifyAudit», схемы «dbo».

Код довольно стандартный код EF:

var auditEvent = new AuditEvent();
auditEvent.EventType = eventType;
auditEvent.Timestamp = timestamp;
auditEvent.UserName = userName;
auditEvent.ApplicationId = this.ApplicationId;

this.objectContext.AddToAuditEvents(auditEvent);
this.objectContext.SaveChanges();

Зачем нам нужно разрешение SELECT для записи в таблицу, и, что более важно: есть ли способ отменить это требование?


EDIT

SQL Profiler показывает выполнение этого оператора:

exec sp_executesql N'insert [dbo].[AuditEvent]([EventType], [Timestamp], [UserName], [ApplicationId])
values (@0, @1, @2, @3)
select [Id]
from [dbo].[AuditEvent]
where @@ROWCOUNT > 0 and [Id] = scope_identity()',N'@0 nvarchar(10),@1 datetimeoffset(7),@2 nvarchar(11),@3 nvarchar(36)',@0=N'UpdateUser',@1='2009-11-10 10:58:33.2814740 +01:00',@2=N'foo',@3=N'bar'

Это объясняет , почему необходимы разрешения SELECT, потому что операция возвращает автоматически сгенерированный идентификатор вставленной строки.

Теперь остается вопрос: мне не нужно знать идентификатор строки, которую я только что вставил, так есть ли способ отключить эту функцию?

Ответы [ 2 ]

8 голосов
/ 10 ноября 2009

По умолчанию, после добавления объекта в ObjectContext и вызова SaveChanges состояние этого объекта изменяется с Добавлен на Неизменен, и он все еще отслеживается ObjectContext. Вот почему EF нужен этот идентификатор, чтобы иметь возможность отслеживать изменения в нем.

Ключи сущностей и добавленные объекты:

1. Объект сущности построен. На данный момент ключевые свойства всех имеют значения по умолчанию, либо ноль, либо 0.

2.Новый объект добавлен в ObjectContext либо по телефону AddObject или один из объектов специфичные для набора методы добавления в контекст или по телефону Добавить на свойство навигации, которое возвращает EntityCollection.

На данный момент, Object Services генерирует временный ключ, который используется для хранения объектов в ObjectStateManager.

3.SaveChanges вызывается на ObjectContext.

Оператор INSERT генерируется Entity Services и выполняется на источник данных.

4.Если операция INSERT завершится успешно, сгенерированные сервером значения записываются вернуться к ObjectStateEntry.

5. ObjectStateEntry обновляет объект сгенерированный сервером значение.

6. Когда AcceptChanges вызывается на ObjectStateEntry, постоянный EntityKey вычисляется с использованием нового сгенерированные сервером значения.

Итак, насколько я знаю, невозможно переключить эту функцию с ObjectContext, и я не вижу никакого «хорошего» решения этой проблемы: один из способов избежать этого - использовать собственные хранимые процедуры. вставить сущность (если можете) (http://msdn.microsoft.com/en-us/library/bb399203.aspx).

Кроме того, если нет идентификаторов, сгенерированных сервером, я думаю, что запрос select не будет выполнен (опять же, если вы можете изменить dbs, и если вы хотите заняться генерацией id).

5 голосов
/ 13 февраля 2014

Тем не менее, это старый вопрос, но в будущем, возможно, кто-нибудь воспользуется. Одним из способов является предоставление права выбора только для полей идентификатора.

...