[英]C# EF6 mapping not applied on select
我在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
方法時,它都會返回正確的對象,但是會丟失FindProjectById
任何引用。 這意味着
ProjectSteps
EmployeesWorkingOnProject
ProjectLeader
沒有設置。 這也導致我的刪除方法出現問題。 我認為這是我的OnModelCreating
方法中的錯誤,但我不確定100%。
誰能告訴我我還缺少哪些獲取子對象的東西?
您已禁用了延遲加載和代理,但是如果您沒有.include()子實體,則EF將不知道要加載它們。 要使用.Include(),您將需要使用.SingleOrDefault()而不是Find。 否則,您將需要轉到上下文以加載子集合/引用。
您的FindProjectById()如下所示:
var project = this.Projects.Include(x=>x.ProjectLeader)
.Include(x=>x.EmployeesWorkingOnProject)
.Include(x=>x.ProjectSteps)
.SingleOrDefault(x=>x.ID == id);
return project;
使用SingleOrDefault與Find的一個警告是,Find將搜索本地存儲,然后轉到DB,Single / First /等將轉到DB。 這意味着每次Find可以在本地內存存儲中找到實體時,都會執行查詢。 如果要將記錄插入數據庫上下文(並在保存更改之前),則搜索該實體將不會返回本地存儲中的一個實體,但尚未提交給數據庫。 (在SaveChanges()之前)
通常,您不希望返回DbContext范圍之外的實體,因為延遲加載代理將不起作用,因此您未預加載的所有內容將為#null。 我通常依賴於延遲執行,將我關心的各個位返回IQueryable然后.Select()放入DTO / ViewModel POCO類中。
如果要自動加載子對象,可以嘗試將延遲加載更改為true 。
this.Configuration.LazyLoadingEnabled = true;
如果延遲加載為false,則需要在訪問之前加載引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.