我们正在采用代码优先的方法,并且在一对多关系方面遇到麻烦。
部门(Dep)拥有员工列表。
每个员工都属于一个部门。 (需要)
我想更新员工姓名。 (不触及部门)
我将样本简化为一些简单的类:
public class Employee
{
[Key]
public int Id { get; set; }
[Required]
public string name { get; set; }
[Required]
public virtual Dep dep { get; set; }
}
public class Dep
{
[Key]
public int Id { get; set; }
[Required]
public string name { get; set; }
public virtual ICollection<Employee> Employees { get; set; }
}
添加新值可以像这样正常工作:
Dep dep = new Dep { name = "My Departement" };
Employee employee = new Employee { name = "My name" };
dep.Employees.Add(employee);
context.Deps.Add(dep);
context.SaveChanges();
但是,如果要更新Employee,就会遇到麻烦。
// Get Employee by Id
Employee employee = Repository.Employees.Single(p => p.Id ==<some id>);
employee.name = "My new name";
context.SaveChanges();
问题1:
如果我们使用
公共虚拟Dep dep {get;组; }
就像上面的代码一样,我们注意到在调试时Employee可以使用Dep对象。浏览对象时,Dep加载得很好。
但是,如果我们像这样将virtual从Employee-class中删除:
公开Dep dep {get;组; }
,则Dep始终为null。奇怪!
为什么会这样呢?难道不是仅凭虚拟决定相关数据是否应该延迟加载?
问题2
由于无论如何我们都想使用虚拟,因此麻烦始于保存更新的Employee。它总是失败,并提示要求Dep。员工已经有一个部门,我不想弄乱它。我只想更改员工的姓名。没有其他的...
为什么在保存员工时失去Dep关系?
我可以在使用虚拟时使它工作,如果我确定Dep也可以通过以下方式手动加载
添加一些代码以读取Dep对象中的某些值
要么
调试和浏览Dep对象
但是,这真的是必需的吗?在这种情况下,我真的不在乎Dep关系。为什么我必须加载Dep数据?
最佳答案
问题2:
这是因为您使用[Required]属性。在这种情况下,您要求框架(不仅是EF)处理所需的约束。
如果只想在EF级别应用约束,则应使用fluent API:
public class testEF : DbContext {
public IDbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Configurations.Add(new EmployeeEFConfiguration());
}
}
public class EmployeeEFConfiguration : EntityTypeConfiguration<Employee> {
public EmployeeEFConfiguration() {
HasRequired(x => x.Dep).WithMany(y => y.Employees);
}
}
我刚刚进行了测试。先前的代码运行。如果我使用RequiredAttribute,则与您有相同的例外。
完整样本:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
namespace testEf6 {
class Program {
static void Main(string[] args) {
using (testEF ctx = new testEF()) {
C2 c2 = new C2 {
Name = "old name",
C1 = new C1 { }
};
ctx.C2s.Add(c2);
ctx.SaveChanges();
}
using (testEF ctx = new testEF()) {
C2 c2 = ctx.C2s.First();
c2.Name = "new name";
ctx.SaveChanges(); // exception here with the attribute ========
}
}
}
public class testEF : DbContext {
public IDbSet<C2> C2s { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
//modelBuilder.Configurations.Add(new C2EFConfiguration());
}
}
public class C2EFConfiguration : EntityTypeConfiguration<C2> {
public C2EFConfiguration() {
HasRequired(x => x.C1).WithMany(y => y.C2s);
}
}
public class C1 {
public int Id { get; set; }
public virtual ICollection<C2> C2s { get; set; }
}
public class C2 {
public int Id { get; set; }
public String Name { get; set; }
[Required]
public virtual C1 C1 { get; set; }
}
}
关于c# - Entity Framework -一对多关系存在问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29967651/