Как я могу иметь столбцы аудита в подходе на основе базы данных с использованием C #? - PullRequest
1 голос
/ 06 июля 2019

Мне нужно добавить столбцы аудита (созданные, созданные, измененные и измененные) для всех таблиц в моем проекте MVC (веб-приложение). Я думал о том, чтобы иметь базовый класс с этими 4 столбцами и наследовать все другие классы. Но я использую подход Database-First, поэтому EF сгенерировал все классы. Я не уверен, как я могу добавить столбцы аудита и наследование базового класса.

Ответы [ 2 ]

0 голосов
/ 06 июля 2019

База данных в первую очередь означает, что вы должны добавить все поля в базу данных вручную, и AFAIK нет наследования. Вы можете написать скрипт SQL, добавляющий эти столбцы. Как сказал Махьяр. Но вам все равно не хватало бы наследства.

Или сначала переключитесь на код. Затем вы можете определить интерфейс и обработать аудит в коде. Как показано здесь . Я, например, использую этот интерфейс:

    /// <summary>
    /// Adds auditing properties to an entity.
    /// </summary>
    public interface IAuditedEntity
    {
        /// <summary>
        /// Date and time of the entity's creation. Usually in UTC.
        /// </summary>
        /// <remarks>Best set via a <see cref="ITimeProvider"/>.</remarks>
        DateTime DateCreated { get; set; }

        /// <summary>
        /// Identification who created this instance.
        /// </summary>
        /// <remarks>Best set via a <see cref="ICurrentUserIdProvider"/>.</remarks>
        string CreatedBy { get; set; }

        /// <summary>
        /// Date and time of last modification. Usually in UTC.
        /// </summary>
        /// <remarks>Best set via a <see cref="ITimeProvider"/>.</remarks>
        DateTime? DateModified { get; set; }

        /// <summary>
        /// Last one modifiying this instance.
        /// </summary>
        /// <remarks>Best set via a <see cref="ICurrentUserIdProvider"/>.</remarks>
       string ModifiedBy { get; set; }
}

Интерфейс провайдера пользователя определяется следующим образом:

    /// <summary>
    /// Interface for providing the current user's id.
    /// </summary>
    public interface ICurrentUserIdProvider
    {
        /// <summary>
        /// Get the id of the curent user.
        /// </summary>
        /// <returns></returns>
        string GetCurrentUserId();
    }

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

0 голосов
/ 06 июля 2019

Я предполагаю, что сначала невозможно выполнить желаемую операцию через базу данных EF. Но чтобы добавить определенные поля во все таблицы базы данных, вы можете использовать следующий код для каждого поля в Sql Server, а затем обновить модель EF.

DECLARE @TableName VARCHAR(100)
DECLARE @TableSchema VARCHAR(100)
DECLARE @COLUMN_NAME VARCHAR(50)
SET @COLUMN_NAME='CreatedOn' 
DECLARE @COLUMN_DATATYPE VARCHAR(50)
SET @COLUMN_DATATYPE='DateTime'

DECLARE CUR CURSOR FOR
  SELECT TABLE_SCHEMA,
         TABLE_NAME
  FROM   INFORMATION_SCHEMA.TABLES
  WHERE  TABLE_TYPE = 'BASE TABLE'
OPEN CUR
FETCH NEXT FROM CUR INTO @TableSchema,@TableName
WHILE @@FETCH_STATUS = 0
  BEGIN

  DECLARE @SQL NVARCHAR(MAX)
  SET @SQL=NULL
  IF NOT EXISTS ( SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS 
       WHERE TABLE_NAME=@TableName AND COLUMN_NAME = @COLUMN_NAME  and Table_Schema=@TableSchema)
  BEGIN
  SET @SQL='ALTER TABLE '+ @TableSchema+'.'+ @TableName +' ADD '+ @COLUMN_NAME + ' '+ @COLUMN_DATATYPE
    PRINT @SQL
    EXEC(@SQL)
  END

  IF EXISTS ( SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS 
              WHERE TABLE_NAME=@TableName AND COLUMN_NAME=@COLUMN_NAME and Table_Schema=@TableSchema)
  BEGIN
    PRINT 'Column Already exists in Table'
  END
      FETCH NEXT FROM CUR INTO @TableSchema,@TableName
  END
CLOSE CUR
DEALLOCATE CUR
...