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



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

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

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);

}

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

  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();
    }
    

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

如此链接所示

您需要使用流畅 API 配置关系。

在不知道您的全部要求的情况下,我将在黑暗中试探一下,这可能是您要找的。

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
}

编辑

如果HasOptionalWithRequired显示红色波浪线,则很可能使用的是 EF CORE,而不是 EF 6,除非在其他地方遇到重大问题。

解决您当前的问题,在您的 Fluent 配置 (OnModelCreating())

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

其次,给定以下配置

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

这意味着:Entity<Student>需要一个SiblingEntity<Sibling>需要一个Student因此,您的配置没有执行您希望它执行的操作。

最后,由于 EF Core 有一些非常智能的约定,它实际上会发现你的nullable外键意味着它是可选的,并且会在没有任何配置的情况下为你创建 (0->0..1) 关系。

解决方案,只需从OnModelCreating()中删除所有流畅的配置,然后让 EF 完成它的工作。 并且不要忘记update-database.

最新更新