Вопрос

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

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

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

В разрешении на выбор был отклонен в объекте «AuditeVent», база данных «Идентификация Audit», Schema '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();

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


РЕДАКТИРОВАТЬ

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'

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

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

Это было полезно?

Решение

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

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

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

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

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

3.saveChanges вызывается в объектномконтексте.

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

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

5. ObjectStateEntry обновляет объект с помощью сервера, сгенерированного значением.

6. Когда принимается acceptchanges в объектном Stateentry, постоянный объект вычисляется с использованием новых сгенерированных серверами значений.

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

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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top