Как обрабатывать дату создания и изменения при миграции .NET MVC Entity Framework?

#asp.net-mvc #database #linq #entity-framework #date

#asp.net-mvc #База данных #linq #entity-framework #Дата

Вопрос:

Как я могу использовать Entity Framework и миграцию, чтобы добавить CreationDate и ModifiedDate к некоторым (не всем) моим модельным классам для автоматического обновления базы данных, а также автоматически обновлять базу данных для этих полей текущим DateTime?

Чтобы было более понятно, это то, что я хотел бы добавить с помощью миграции к двум моим таблицам базы данных:

 CreationDate   DATETIME    DEFAULT NULL,
ModifiedDate   TIMESTAMP   ON UPDATE CURRENT_TIMESTAMP
  

Я добавил их в модель следующим образом:

 public DateTime? CreationDate { get; set; }
public int ModifiedDate { get; set; }
  

Моя единственная идея, которая у меня была до сих пор, это: переопределить DbContext#SaveChanges() что-то вроде:

 public void SaveChanged()
{
    // Somehow check if the Tables in the Data I want to update contains a ModifiedDate
    // or Data I want to create contains a CreationDate
    // And add them with the current DateTime if these fields are present in the table(s)

    base.SaveChanges();
}
  

Я даже не знаю, возможно ли это вышеописанное и как я могу получить доступ к LINQ-запросу, который я хочу использовать в базе данных, но если это правильное направление, что мне следует указать в строках комментариев? И если это неправильный способ обработки этого, как мне тогда это сделать?

TL; DR: Как использовать миграцию Entity Framework для модели (-Field), чтобы она использовала ON UPDATE CURRENT_TIMESTAMP ?

Комментарии:

1. Не совсем понятно, вы ищете миграцию или вы выполнили миграцию данных и теперь ищете, как выполнить CRUD для данных?

2. @AshishRajput Я хочу выполнить автоматическую миграцию с использованием .NET mvc Entity Framework для изменения двух моих таблиц, чтобы она добавила поля CreationDate и ModifiedDate, и я также хочу автоматически заполнить эти CreationDate и ModifiedDate в этих двух таблицах DB текущими DateTime непосредственно перед или при вызове MyDB.SaveChanges() .

Ответ №1:

Если вы включите автоматическую миграцию, модель будет обновлена при первом экземпляре DbContext вашего приложения в вашем приложении. Обычно это происходит при первом использовании приложения DbContext для некоторых операций CRUD, но это также может быть вызвано вызовом DbContext.Database.Initialize метода. Но вам не нужно этого делать!!

Чтобы понять, как включить автоматическую миграцию и как она работает, внимательно прочитайте этот документ: Автоматическая миграция первого кода в MSDN. Вы можете легко перейти от этого документа к другим связанным, чтобы улучшить свое понимание EF.

Атрибуты в вашем классе верны, но вам не нужно указывать атрибуты, относящиеся к DateTime свойству: соглашения EF приведут свойство DateTime к желаемому типу на стороне базы данных (в данном случае к обнуляемому DATETIME).

ПРИМЕЧАНИЕ: временная метка не имеет ничего общего с датой, это увеличивающееся число для обозначения «версии» строки, то есть она меняется всякий раз, когда строка обновляется, но это не дата, а число

Комментарии:

1. Я только что поспрашивал в своей компании людей, у которых немного больше опыта в миграции EF, так что теперь я знаю немного больше о том, как это работает. Тем не менее, спасибо за ответ и ссылку. Но моя главная проблема заключается в том, как использовать миграцию, чтобы дата создания автоматически заполнялась всякий раз, когда я добавляю элемент в одну из этих двух таблиц базы данных, и как дата изменения автоматически обновляется всякий раз, когда я обновляю элемент в одной из этих двух таблиц базы данных. Может быть, мне следует немного перефразировать свой вопрос: «Как добавить ModifiedDate с ON UPDATE CURRENT_TIMESTAMP в таблицу базы данных с помощью Entity Framework?»

2. Если вы чувствуете, что должны изменить свой вопрос, тогда идите, измените его, объясните, что вам нужно. Вы не получите нужного ответа, задав неправильный вопрос. Думаю, я ответил на ваш вопрос…

3. Хотя я не возражаю против ответа о том, как использовать миграцию с EF в целом, поскольку я тоже в некотором роде новичок в этом, я спросил о том, как обрабатывать даты создания и изменения с помощью миграции EF конкретно. На эту часть моего вопроса пока нет ответа. Возможно, теперь более ясно, чего я хочу достичь с помощью отредактированного вопроса..

4. Чтобы было понятно, миграции могут использоваться только для обновления базы данных, соответствующей изменениям модели Code First. Не более того. Итак, вы задали вопрос, на который невозможно ответить. Я объяснил, что вы можете делать с миграциями. Если вам нужно сделать что-то другое, это не имеет ничего общего с миграциями, и его следует задать в совершенно новом, совершенно другом вопросе. Пожалуйста, не тратьте свое время на создание этого нового вопроса.

Ответ №2:

Я знаю, что это устарело, но единственный ответ даже близко не подходит к ответу на правильный вопрос!

Вот как это сделать:

Просто зациклите коллекцию ChangeTracker в DbContext следующим образом:

 public virtual int SaveChanges()
{
    foreach (var item in this.ChangeTracker.Entries())
    {
        var now = DateTime.UtcNow;
        var modelBase = item.Entity as IModelBase;
        if (modelBase != null)
        {
            switch (item.State)
            {
                case EntityState.Added:
                    modelBase.CreatedOn = now;
                    goto case EntityState.Modified;

                case EntityState.Modified:
                    modelBase.LastModifiedOn = now;
                    break;

                default:
                    break;
            }
        }
    }
    return base.SaveChanges();
}
  

Вам также нужен интерфейс и, желательно, базовый класс, как показано ниже:

 /// <summary>New interface classes should implement if they already have a base class.</summary>
/// 
public interface IModelBase
{
    [Key]
    string Id { get; set; }

    DateTime CreatedOn { get; set; }
    DateTime LastModifiedOn { get; set; }

    string CreatedById { get; set; }
    string LastModifiedById { get; set; }
}
/// <summary>Base class model classes should inherit if they do not have an existing base class. Any MVC framework classes with existing base classes should implement the interface instead.</summary>
/// 
public class ModelBase:IModelBase
{
    [Key]
    public string Id { get; set; }

    public DateTime CreatedOn { get; set; }
    public DateTime LastModifiedOn { get; set; }

    public string CreatedById { get; set; }
    public string LastModifiedById { get; set; }
}
  

Затем, наконец, ваши классы модели должны либо наследовать базовый класс, либо реализовать интерфейс:

 public class MyTrackedClass : ModelBase
{
     // Your code here!
}
  

Или

 public class MyTrackedClass : IModelBase
{
    [Key]
    public string Id { get; set; }

    public DateTime CreatedOn { get; set; }
    public DateTime LastModifiedOn { get; set; }

    public string CreatedById { get; set; }
    public string LastModifiedById { get; set; }
     // Your code here!
}