Заполнить созданный и LastModified автоматически в EF Core - PullRequest
0 голосов
/ 07 ноября 2018

Надеемся на создание инфраструктуры (без шаблона хранилища для работы с DbSets напрямую) для автоматического заполнения Создается и последний раз изменяется автоматически, а не выплевывает эти коды из базы кода.

Не могли бы вы указать мне в правильном направлении, как этого достичь.

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

.ctor()
    {
        Created = DateTime.Now;
        LastModified = DateTime.Now;
    }

public interface IHasCreationLastModified
    {
        DateTime Created { get; set; }
        DateTime? LastModified { get; set; }
    }

public class Account : IEntity, IHasCreationLastModified
{
    public long Id { get; set; }

    public DateTime Created { get; set; }
    public DateTime? LastModified { get; set; }
    public virtual IdentityUser IdentityUser { get; set; }
}

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Начиная с версии 2.1, EF Core предоставляет События изменения состояния :

Новые Tracked и StateChanged события на ChangeTracker могут использоваться для записи логики, которая реагирует на объекты, входящие в DbContext или изменяющие их состояние.

Вы можете подписаться на эти события из вашего DbContext конструктора

ChangeTracker.Tracked += OnEntityTracked;
ChangeTracker.StateChanged += OnEntityStateChanged;

и сделайте что-то вроде этого:

void OnEntityTracked(object sender, EntityTrackedEventArgs e)
{
    if (!e.FromQuery && e.Entry.State == EntityState.Added && e.Entry.Entity is IHasCreationLastModified entity)
        entity.Created = DateTime.Now;
}

void OnEntityStateChanged(object sender, EntityStateChangedEventArgs e)
{
    if (e.NewState == EntityState.Modified && e.Entry.Entity is IHasCreationLastModified entity)
        entity.LastModified = DateTime.Now;
}
0 голосов
/ 07 ноября 2018

Одним из возможных решений (которое мы используем в настоящее время там, где я работаю) является переопределение метода SaveChanges() в DbContext и добавление небольшого кода для циклического просмотра измененных объектов, устанавливающих значения

public override int SaveChanges()
{
    var changedEntriesCopy = ChangeTracker.Entries()
                .Where(e => e.State == EntityState.Added ||
                e.State == EntityState.Modified ||
                e.State == EntityState.Deleted)
                .ToList();
    var saveTime = DateTime.Now;

        foreach (var entityEntry in changedEntriesCopy)
        {
            if (entityEntry.Metadata.FindProperty("Created") != null && entityEntry.Property("Created").CurrentValue == null)
            {
                entityEntry.Property("Created").CurrentValue = saveTime;
            }

            if (entityEntry.Metadata.FindProperty("Updated") != null)
            {
                entityEntry.Property("Updated").CurrentValue = saveTime;
            }
        }
    return base.SaveChanges();
}

Наша ситуация в основном настроена примерно так: создание в нашей ситуации обнуляется, так что при создании новой сущности значение в коде равно нулю до создания (что позволяет легко проверить, заполнялось ли когда-либо созданное).

Могут быть и другие решения, но это было проще всего настроить для нас, и не оказало заметного влияния на производительность

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...