我试图使用一对一的关系模型对数据库进行更新,但只有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; }
}
其余相关的模型类Parents
、Education
、Guardian
与Siblings
相同。
我怎样才能确保更新跨越所有字段。谢谢。
编辑
这是我在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);
}
我建议您尝试以下两种方法:
-
修改导航属性
_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;
-
使用
_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
}
编辑
如果HasOptional
和WithRequired
显示红色波浪线,则很可能使用的是 EF CORE,而不是 EF 6,除非在其他地方遇到重大问题。
解决您当前的问题,在您的 Fluent 配置 (OnModelCreating()
)
首先,您要查找的不是如何配置一对一关系。 您打算配置一对零或一关系。
其次,给定以下配置
builder.Entity<Student>()
.HasOne(s => s.Siblings)
.WithOne(s => s.Student);
这意味着:Entity<Student>
需要一个Sibling
,Entity<Sibling>
需要一个Student
因此,您的配置没有执行您希望它执行的操作。
最后,由于 EF Core 有一些非常智能的约定,它实际上会发现你的nullable
外键意味着它是可选的,并且会在没有任何配置的情况下为你创建 (0->0..1) 关系。
解决方案,只需从OnModelCreating()
中删除所有流畅的配置,然后让 EF 完成它的工作。 并且不要忘记update-database
.