EF Core устанавливает исходные значения в отключенном сценарии - PullRequest
1 голос
/ 26 апреля 2019

Я использую DBContext.Update(ParentEntity) для обновления объекта. Затем я перебираю каждую из сущностей property.CurrentValue и property.OriginalValue. Проблема, с которой я сталкиваюсь, заключается в том, что CurrentValues ​​ и OriginalValues ​​ одинаковы, даже если одно свойство было изменено и отличается от БД. Я ожидал получить OriginalValues ​​ из базы данных. Вот цикл, который происходит перед сохранением изменений.

foreach (var entry in ChangeTracker.Entries())
        {
            if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged ||entry.Entity is ChangelogUser)
                continue;

            var auditEntry = new AuditEntry(entry) {TableName = entry.Metadata.Relational().TableName};
            auditEntries.Add(auditEntry);

            foreach (var property in entry.Properties)
            {
                if (property.IsTemporary)
                {
                    // value will be generated by the database, get the value after saving
                    auditEntry.TemporaryProperties.Add(property);
                    continue;
                }

                string propertyName = property.Metadata.Name;
                if (property.Metadata.IsPrimaryKey())
                {
                    auditEntry.KeyValues[propertyName] = property.CurrentValue;
                    continue;
                }

                switch (entry.State)
                {
                    case EntityState.Added:
                        auditEntry.NewValues[propertyName] = property.CurrentValue;
                        break;

                    case EntityState.Deleted:
                        auditEntry.OldValues[propertyName] = property.OriginalValue;
                        break;

                    case EntityState.Modified:
                        if (property.CurrentValue != null)
                        {
                            if (property.OriginalValue != null && property.CurrentValue != null)
                            {
                                if (property.IsModified && !property.CurrentValue.Equals(property.OriginalValue))
                                {
                                    auditEntry.OldValues[propertyName] = property.OriginalValue;
                                    auditEntry.NewValues[propertyName] = property.CurrentValue;
                                }
                            }
                        }

                        break;
                }
            }

Из этого кода я ВСЕГДА получаю одинаковые исходные и текущие значения. Есть ли способ получить исходные значения из БД и установить их в сущности?

1 Ответ

1 голос
/ 29 апреля 2019

Поскольку довольно сложно получить ответ на вопросы EFCore, вот решение, которое я придумала.

Ознакомьтесь с разделом State.Modified . Я перебираю каждую сущность, а затем перебираю каждое свойство. В этом случае я использую текущие и исходные значения для сравнения и добавляю их в свою таблицу аудита только тогда, когда что-то изменилось.

На конце метода я удаляю сущности, которые не изменились, из моей таблицы аудита. Простая мимле

Вы можете использовать это var databaseValues = entry.GetDatabaseValues(); To для ваших пользовательских отключенных сценариев.

var auditEntries = new List<AuditEntry>();
        foreach (var entry in ChangeTracker.Entries())
        {

            if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged)
                continue;

            var auditEntry = new AuditEntry(entry) {TableName = entry.Metadata.Relational().TableName};
            auditEntries.Add(auditEntry);

            var databaseValues = entry.GetDatabaseValues();

            foreach (var property in entry.Properties)
            {
                if (property.IsTemporary)
                {
                    // value will be generated by the database, get the value after saving
                    auditEntry.TemporaryProperties.Add(property);
                    continue;
                }

                string propertyName = property.Metadata.Name;
                if (property.Metadata.IsPrimaryKey())
                {
                    auditEntry.KeyValues[propertyName] = property.CurrentValue;
                    continue;
                }

                switch (entry.State)
                {
                    case EntityState.Added:
                        auditEntry.NewValues[propertyName] = property.CurrentValue;
                        break;

                    case EntityState.Deleted:
                        auditEntry.OldValues[propertyName] = property.OriginalValue;
                        break;

                    case EntityState.Modified:
                        if (property.CurrentValue != null)
                        {
                            if (databaseValues[propertyName] != null && property.CurrentValue != null)
                            {
                                if (property.IsModified && !property.CurrentValue.Equals(databaseValues[propertyName]))
                                {
                                    auditEntry.OldValues[propertyName] = databaseValues[propertyName];
                                    auditEntry.NewValues[propertyName] = property.CurrentValue;
                                }
                            }
                        }

                        break;
                }
            }

            if (auditEntry.NewValues.Equals(auditEntry.OldValues) || auditEntry.NewValues.Count == 0 && auditEntry.OldValues.Count == 0)
            {
                auditEntries.Remove(auditEntry);
            }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...