简体   繁体   English

C#EF6映射未应用于选择

[英]C# EF6 mapping not applied on select

I am facing an issue with the Fluent API mapping in EF6. 我在EF6中遇到了Fluent API映射问题。 It is all set up, but for some reason, anytime I select an object, it is missing the child objects. 全部设置完毕,但是由于某种原因,无论何时我选择一个对象,它都会丢失子对象。

Lets start with the DbContext : 让我们从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);
    }
}

This is pretty much everything needed which plays into my issue. 这几乎是需要解决的所有问题。

I have set up a total of 3 model classes: 我总共设置了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; }
}

And the corresponding database setup: 以及相应的数据库设置:

在此处输入图片说明

Now to my problem. 现在到我的问题。 Whenever I execute the FindProjectById method it does return the proper object, but it is missing any reference to the childs. 每当我执行FindProjectById方法时,它都会返回正确的对象,但是会丢失FindProjectById任何引用。 this means that 这意味着

  • ProjectSteps
  • EmployeesWorkingOnProject
  • ProjectLeader

are not set. 没有设置。 This also causes issues on my delete methods. 这也导致我的删除方法出现问题。 I assume that this is an error in my OnModelCreating method, but I am not 100% sure. 我认为这是我的OnModelCreating方法中的错误,但我不确定100%。

Can anyone tell me what I am missing to fetch the child objects as well? 谁能告诉我我还缺少哪些获取子对象的东西?

You have disabled lazy loading and proxies, but if you do not .Include() child entities then EF doesn't know to load them. 您已禁用了延迟加载和代理,但是如果您没有.include()子实体,则EF将不知道要加载它们。 To use .Include() you will need to use .SingleOrDefault() rather than Find. 要使用.Include(),您将需要使用.SingleOrDefault()而不是Find。 Otherwise you will need to go to the context to Load child collections/references. 否则,您将需要转到上下文以加载子集合/引用。

Your FindProjectById() would look something like: 您的FindProjectById()如下所示:

var project = this.Projects.Include(x=>x.ProjectLeader)
  .Include(x=>x.EmployeesWorkingOnProject)
  .Include(x=>x.ProjectSteps)
  .SingleOrDefault(x=>x.ID == id); 
return project; 

A caveat around using SingleOrDefault vs. Find is that where Find will search local store then go to DB, Single/First/ etc. will go to DB. 使用SingleOrDefault与Find的一个警告是,Find将搜索本地存储,然后转到DB,Single / First /等将转到DB。 This means that a query is executed each time where Find may find an entity in the local memory store. 这意味着每次Find可以在本地内存存储中找到实​​体时,都会执行查询。 if you're inserting records into the DB Context (and prior to save changes) searching for that entity will not return an entity that is in the local store, but hasn't been committed to the DB yet. 如果要将记录插入数据库上下文(并在保存更改之前),则搜索该实体将不会返回本地存储中的一个实体,但尚未提交给数据库。 (prior to SaveChanges()) (在SaveChanges()之前)

Typically you do not want to return entities outside of the scope of the DbContext as lazy load proxies won't work so anything you don't pre-load will be #null. 通常,您不希望返回DbContext范围之外的实体,因为延迟加载代理将不起作用,因此您未预加载的所有内容将为#null。 I generally rely on deferred execution, returning IQueryable then .Select() the various bits I care about into DTO/ViewModel POCO classes. 我通常依赖于延迟执行,将我关心的各个位返回IQueryable然后.Select()放入DTO / ViewModel POCO类中。

You can try change the lazy loading into true if you want to automatically load the child objects. 如果要自动加载子对象,可以尝试将延迟加载更改为true

this.Configuration.LazyLoadingEnabled = true;

if the lazy loading is false, then you need to load the reference before accessing it. 如果延迟加载为false,则需要在访问之前加载引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM