【发布时间】:2018-04-28 00:11:39
【问题描述】:
我遇到了 EF6 中的 Fluent API 映射问题。一切都设置好了,但由于某种原因,每当我选择一个对象时,它都会丢失子对象。
让我们从DbContext开始:
public partial class PMSContext : DbContext
{
public PMSContext() : base(nameOrConnectionString: "PmsDb")
{
this.Configuration.ProxyCreationEnabled = false;
this.Configuration.LazyLoadingEnabled = false;
}
public DbSet<Employee> employees { get; set; }
public DbSet<Project> projects { get; set; }
public DbSet<ProjectStep> projectSteps { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Employee>().HasMany(e => e.Projects).WithMany(t => t.EmployeesWorkingOnProject).Map(m =>
{
m.MapLeftKey("EmployeeId");
m.MapRightKey("ProjectId");
m.ToTable("employee_project");
});
modelBuilder.Entity<ProjectStep>().HasRequired(p => p.Project).WithMany(s => s.ProjectSteps).Map(m => m.MapKey("Project")).WillCascadeOnDelete(true);
//modelBuilder.Entity<Project>().HasMany(p => p.ProjectSteps).WithRequired(ps => ps.Project).WillCascadeOnDelete(true);
modelBuilder.Entity<Employee>().HasOptional<Project>(e => e.LeaderOfProject).WithOptionalPrincipal(p => p.ProjectLeader).Map(m => m.MapKey("ProjectLeader"));
}
public Project FindProjectById(int id)
{
return this.projects.Find(id);
}
}
这几乎是我的问题所需要的一切。
我一共设置了3个模型类:
[DataContract(Namespace = "Shared")]
public class Employee
{
public Employee()
{
this.Projects = new List<Project>();
}
[DataMember]
public int ID { get; set; }
[DataMember]
public String Name { get; set; }
[DataMember]
public String JobDescription { get; set; }
[DataMember]
public String Department { get; set; }
[DataMember]
public String DirectDialing { get; set; }
[DataMember]
public bool Status { get; set; }
public virtual Project LeaderOfProject { get; set; }
[DataMember]
public virtual List<Project> Projects { get; set; }
}
[DataContract(Namespace = "Shared")]
public class Project
{
public Project()
{
this.EmployeesWorkingOnProject = new List<Employee>();
this.ProjectSteps = new List<ProjectStep>();
}
[DataMember]
public int ID { get; set; }
[DataMember]
public String Titel { get; set; }
[DataMember]
public DateTime StartDate { get; set; }
[DataMember]
public DateTime EndDate { get; set; }
[DataMember]
public String Description { get; set; }
[DataMember]
public Employee ProjectLeader { get; set; }
[DataMember]
public bool Status { get; set; }
[DataMember]
public virtual List<Employee> EmployeesWorkingOnProject { get; set; }
[DataMember]
public virtual List<ProjectStep> ProjectSteps { get; set; }
}
[DataContract(Namespace = "Shared")]
[Table("project_step")]
public class ProjectStep
{
[DataMember]
public int ID { get; set; }
[DataMember]
public String Description { get; set; }
[DataMember]
public DateTime StartDate { get; set; }
[DataMember]
public DateTime EndDate { get; set; }
[DataMember]
public Project Project { get; set; }
}
以及对应的数据库设置:
现在我的问题。每当我执行FindProjectById 方法时,它都会返回正确的对象,但它缺少对子对象的任何引用。这意味着
ProjectStepsEmployeesWorkingOnProjectProjectLeader
未设置。这也会导致我的删除方法出现问题。我认为这是我的 OnModelCreating 方法中的错误,但我不是 100% 确定。
谁能告诉我在获取子对象时我还缺少什么?
【问题讨论】:
-
数据库中是否也创建了外键约束?
-
您已禁用延迟加载和代理,但如果您不使用 .Include() 子实体,则 EF 不知道加载它们。要使用 .Include(),您需要使用 .SingleOrDefault() 而不是 Find。否则,您将需要转到上下文以加载子集合/引用。
-
@StevePy 我需要
Include()并启用代理 = false 和延迟加载吗?我删除了this.Configuration.LazyLoadingEnabled = false;行,但现在它仍然没有加载子实体。我也尝试过启用代理,但这会导致错误提示Connection was closed by remote host -
您可以在没有代理的情况下使用 .Include(),您的 FindProjectById() 看起来像: var project = this.Projects.Include(x=>x.ProjectLeader).Include(x=>x .EmployeesWorkingOnProject).Include(x=>x.ProjectSteps).SingleOrDefault(x=>x.ID == id);返回项目;通常,您不希望返回 DbContext 范围之外的实体,因为延迟加载代理将不起作用,因此您未预加载的任何内容都将是 #null。我通常依赖延迟执行,返回 IQueryable
然后 .Select() 我关心的各种位到 DTO/ViewModel POCO 类中。 -
@StevePy 非常感谢。它工作得很好。如果您愿意,可以将您的 cmets 转换为答案,我会接受它
标签: c# .net entity-framework orm entity-framework-6