簡體   English   中英

C#EF6映射未應用於選擇

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM