EF Core не отправляет все измененные поля для обновления - PullRequest
1 голос
/ 04 мая 2020

Я делаю простое обновление (использую EF Core 3.1.2 с SQL backend) и не смог узнать, почему одно поле не может быть отправлено в БД.

У меня есть вызов обновления, где я вижу значение DateModified, которое я хочу отправить: enter image description here

Однако, используя SQL Профилировщик, я вижу, что это то, что на самом деле отправляется, и поле DateModified НЕ отправляется SQL вообще:

enter image description here

Здесь объект пытается отправить:

public class AVO : BasePropertiesWithID
{
    //[Authorize(Policy = "AllEmployees")]
    [ForeignKey("DivisionID")]
    public int DivisionID { get; set; }
    [Required]
    public int AccountNumber { get; set; }
    [Required]
    public string CustomerName { get; set; }
    [Required]
    public string Comments { get; set; }
    public bool IsActive { get; set; }
    public DateTime? StartDate { get; set; }
    public DateTime? EndDate { get; set; }

    [UseFiltering]
    [UseSorting]
    public virtual Division Division { get; set; }
}

А вот базовый класс, который содержит поле DateModified (не отправляется) и поле DateInserted, которое отправляется:

    public class BasePropertiesWithID
{
    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [Required]
    [Column(Order = 9990)]
    [DefaultValue("autoProcess")]
    public string InsertedBy { get; set; }

    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
    [Required]
    [Column(Order = 9991)]
    public DateTime DateInserted { get; set; }

    [Required]
    [Column(Order = 9992)]
    [DefaultValue("autoProcess")]
    public string ModifiedBy { get; set; }

    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
    [Required]
    [Column(Order = 9993)]
    public DateTime DateModified { get; set; }

}

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

Почему поле не может быть отправлено? Кто-нибудь может предложить ПОЧЕМУ или как это решить ?? СПАСИБО!

РЕДАКТИРОВАТЬ: Как этот объект добавляется в EF enter image description here enter image description here enter image description here enter image description here

1 Ответ

2 голосов
/ 04 мая 2020

Почему поле не может быть даже отправлено?

Поскольку вы настроили свойство для создания его значения при добавлении или обновлении:

enter image description here

, который инструктирует EF перезагружать это значение из базы данных после каждого обновления. Чтобы применить обновления на стороне клиента, вы должны установить SetAfterSaveBehavior на PropertySaveBehavior.Save в модели следующим образом:

modelBuilder.Entity<Person>().Property(b => b.ModifiedAt).Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Save);

например,

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.SqlServer;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;

namespace EfCore3Test
{

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime ModifiedAt { get; set; }
    }

    public class Db : DbContext
    {

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Person>().Property(p => p.ModifiedAt).HasDefaultValueSql("getdate()").ValueGeneratedOnAddOrUpdate();

            modelBuilder.Entity<Person>().Property(b => b.ModifiedAt).Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Save);

        }
        private static readonly ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
        {
            builder.AddFilter((category, level) =>
               category == DbLoggerCategory.Database.Command.Name
               && level == LogLevel.Information).AddConsole();
        });


        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseLoggerFactory(loggerFactory)
                          .UseSqlServer("Server=.;database=EfCore3Test;Integrated Security=true",
                                        o => o.UseRelationalNulls());

            base.OnConfiguring(optionsBuilder);
        }
    }





    class Program
    {

        static void Main(string[] args)
        {


            using var db = new Db();

            db.Database.EnsureDeleted();
            db.Database.EnsureCreated();

            var p = new Person() { Name = "Fred" };
            db.Set<Person>().Add(p);
            db.SaveChanges();

            p.Name = "Fred2";
            p.ModifiedAt = DateTime.Now.AddDays(-7);
            db.Set<Person>().Update(p);
            db.SaveChanges();


        }
    }
  }
}

output

info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[@p2='?' (DbType = Int32), @p0='?' (DbType = DateTime2), @p1='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']
      SET NOCOUNT ON;
      UPDATE [Person] SET [ModifiedAt] = @p0, [Name] = @p1
      WHERE [Id] = @p2;
      SELECT @@ROWCOUNT;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...