8

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

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

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

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

код довольно стандартный код 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(); 

Почему нам нужно ВЫБЕРИТЕ разрешение на запись в таблице, и что еще более важно: есть ли способ, мы можем удалить это требование?


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, разрешения, поскольку операция возвращает автоматически сгенерированный идентификатор вставленной строки.

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

+0

Что показывает SQL Profiler? –

+1

Отредактированный вопрос, включающий данные SQL Profiler. –

ответ

8

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

Entity Keys and added objects:

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

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

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

3.SaveChanges вызывается в объекте Object4online .

Оператор INSERT создается Службами сущностей и выполняется на источнике данных .

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

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

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

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

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

3

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