我们正在采用代码优先的方法,并且在一对多关系方面遇到麻烦。


部门(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/

10-12 02:39