EF无法更新一对一或一个关系字段,但会更新其余字段

时间:2019-07-15 09:14:17

标签: c# asp.net-core entity-framework-core

我正尝试使用一对一的关系模型对数据库进行更新,但是只有Student model 字段是唯一起作用的字段。我如何也可以更新其余部分?

这是我的存储库更新方法:

 public void Edit(Student student)
        {
            var existingStudent = _context.Students
                .Include(e => e.Education)
                .Include(s => s.Siblings)
                .Include(p => p.Parents)
                .Include(g => g.Guardian)
                .Single(s => s.Id == student.Id);

            if (existingStudent != null)
            {
                // do some updating.
                _context.Attach(existingStudent);
                _context.Entry(existingStudent).CurrentValues.SetValues(student);
                _context.Entry(existingStudent).State = EntityState.Modified;
                _context.SaveChanges();

            }


        }

然后,这是我的Student 模型课:

public class Student
    {
        [Key]
        public long Id { get; set; }
        [Display(Name="First Name")]
        public string FirstName { get; set; }
        [Display(Name="Middle Name")]
        public string MiddleName { get; set; }
        [Display(Name="Last Name")]
        public string LastName { get; set; }
        [Display(Name="Nationality")]
        public string Nationality { get; set; }
        [Display(Name="Gender")]
        public string Gender { get; set; }
        [Display(Name="Religion")]
        public string Religion { get; set; }
        [Display(Name="Medical Condition")]
        public string MedicalCondition { get; set; }
        [Display(Name="Deceased")]
        public string Deceased { get; set; }
        [Display(Name="Home Address")]
        public string HomeAddress { get; set; }
        [Display(Name="Country Of Residence")]
        public string CountryOfResidence { get; set; }
        [Display(Name="City")]
        public string City { get; set; }
        [Display(Name="Date Of Birth")]
        public DateTime DateOfBirth { get; set; }
        public int Age { get; set; }
        public virtual Parents Parents { get; set; }
        public virtual Education Education { get; set; }
        public virtual Guardian Guardian { get; set; }
        public virtual Siblings Siblings { get; set; }
    }

然后一对一的关系类如下:

public class Siblings
    {
        public long Id { get; set; }
        [Display(Name="Number of Brothers")]
        public int NumberOfBrothers { get; set; }
        [Display(Name="Number of Sisters")]
        public int NumberOfSisters { get; set; }

        public Student Student { get; set; }

        public  long? StudentId { get; set; }
    }

其余相关模型类ParentsEducationGuardianSiblings相同。

如何确保更新覆盖所有字段。谢谢。

编辑

这就是我在OnModelCreating()中所拥有的:

protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<Student>()
                .HasOne(e => e.Education)
                .WithOne(s => s.Student)
                ;


            builder.Entity<Student>()
                .HasOne(g => g.Guardian)
                .WithOne(s => s.Student);

            builder.Entity<Student>()
                .HasOne(p => p.Parents)
                .WithOne(s => s.Student);

            builder.Entity<Student>()
                .HasOne(s => s.Siblings)
                .WithOne(s => s.Student);


            builder.Entity<Education>()
                .HasOne(s => s.Student)
                .WithOne(e => e.Education);
            builder.Entity<Guardian>()
                .HasOne(s => s.Student)
                .WithOne(g => g.Guardian);

            builder.Entity<Parents>()
                .HasOne(s => s.Student)
                .WithOne(p => p.Parents);

            builder.Entity<Siblings>()
                .HasOne(s => s.Student)
                .WithOne(p => p.Siblings);


}

2 个答案:

答案 0 :(得分:0)

我不确定您是否有任何Fluent配置,但是如果没有,

in this link

您需要使用Fluent API配置关系。

在不知道您的完整要求的情况下,我将暗中暗暗怀疑这可能是您想要的。

dotnet build

编辑

如果protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Student>() .HasOptional(s => s.Siblings) // Mark Siblings property optional in Student entity .WithRequired(ad => ad.Student); // mark Student property as required in Siblings entity. Cannot save Siblings without Student } HasOptional给了您红色的曲线,那么您很可能会使用EF CORE,而不是EF 6,除非您在其他地方遇到了重大问题。

使用Fluent配置(WithRequired)解决当前问题

首先,您要寻找的不是如何配置一对一关系。您打算配置一对零或一种关系。

第二,给出以下配置

OnModelCreating()

这意味着:builder.Entity<Student>() .HasOne(s => s.Siblings) .WithOne(s => s.Student); 需要一个Entity<Student>,而Sibling需要一个Entity<Sibling>,因此您的配置没有执行您想要的操作。

最后,由于EF Core具有一些非常聪明的约定,因此它实际上会发现您的Student外键意味着它是可选的,并且会为您创建(0-> 0..1)关系,而无需任何配置。

该解决方案,只需从nullable中删除所有流利的配置,然后让EF来完成即可。而且不要忘了OnModelCreating()

答案 1 :(得分:0)

我建议您尝试以下两种方法:

  1. 修改导航属性

    _context.Entry(existingStudent).CurrentValues.SetValues(student);
    _context.Entry(existingStudent).State = EntityState.Modified;
    _context.Entry(existingStudent.Siblings).CurrentValues.SetValues(student.Siblings);
    _context.Entry(existingStudent.Siblings).State = EntityState.Modified;
    
  2. 使用_context.Update

    更新
    var existingStudent = _context.Student
        .Include(s => s.Siblings)
        .AsNoTracking()
        .Single(s => s.Id == 4);
    
    if (existingStudent != null)
    {
        existingStudent = student;
        _context.Update(existingStudent);
        _context.SaveChanges();
    }