2017-10-05 203 views
0

我有项目类,其中每个项目都有其工作订单。 这些都是在MySQLEF流利的API - 获取相关实体

CREATE TABLE `project` (
    `idProject` INT(11) NOT NULL AUTO_INCREMENT, 
    `idCompany` INT(11) NOT NULL, 
    `Title` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci', 
    PRIMARY KEY (`idProject`, `idCompany`), 
    INDEX `FK_project_company` (`idCompany`), 
    CONSTRAINT `FK_project_company` FOREIGN KEY (`idCompany`) REFERENCES `company` (`idCompany`) ON UPDATE NO ACTION ON DELETE NO ACTION 
) 
; 

CREATE TABLE `project_workorders` (
    `idProjectWO` INT(11) NOT NULL AUTO_INCREMENT, 
    `idProject` INT(11) NOT NULL DEFAULT '0', 
    `idWorkOrder` INT(11) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`idProjectWO`, `idProject`, `idWorkOrder`), 
    INDEX `FK_project_workorders_project` (`idProject`), 
    INDEX `FK_project_workorders_workorder` (`idWorkOrder`), 
    CONSTRAINT `FK_project_workorders_project` FOREIGN KEY (`idProject`) REFERENCES `project` (`idProject`) ON UPDATE NO ACTION ON DELETE NO ACTION, 
    CONSTRAINT `FK_project_workorders_workorder` FOREIGN KEY (`idWorkOrder`) REFERENCES `workorder` (`idWorkOrder`) ON UPDATE NO ACTION ON DELETE NO ACTION 
); 

创建表,然后有FluentAPI配置文件

class ProjectConfiguration : EntityTypeConfiguration<Project> 
    { 
     internal ProjectConfiguration() 
     { 
      this.HasKey(p => new { p.idProject , p.idCompany}); 
      this.Property(p => p.idProject) 
       .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
      this.HasRequired<MaxUser>(p => p.CreatedByUser) 
       .WithMany() 
       .HasForeignKey(p => p.CreatedByID); 
      this.HasMany(s => s.ProjectWO) 
       .WithRequired(w=>w.Project) 
       .HasForeignKey(k=>new { k.idProject,k.idProjectWO}); 
      this.Map(m => 
      { 
       m.MapInheritedProperties(); 
      }); 
     } 
    } 

    class ProjectWOConfiguration : EntityTypeConfiguration<ProjectWO> 
    { 
     internal ProjectWOConfiguration() 
     { 
      this.HasKey(p=> new { p.idProjectWO , p.idProject, p.idWorkOrder }); 
      this.Property(p => p.idProjectWO) 
       .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
      this.HasRequired<MaxUser>(p => p.CreatedByUser) 
       .WithMany() 
       .HasForeignKey(p => p.CreatedByID); 
      this.Map(m => 
      { 
       m.MapInheritedProperties(); 
      }); 
     } 
    } 

的问题是出现在项目的对象,我不能得到相关的实体。 不管我尝试什么,ProjectWO子对象总是空的。

enter image description here

任何帮助表示赞赏。

+0

我的第一个猜测是此组合键周围。如果你喜欢的东西多租户场景处理,然后在顶层实体使用这些,但只要有可能,避免他们在下级实体。例如,对于ProjectWO,这看起来像一个链接项目和WO之间的g表? PK可以是idProjectWO。它可以包含2个FK,一个用于项目,另一个用于WorkOrder。没有必要创建一个组合键。在大多数情况下,我离开了FK领域的子实体,并使用.MAP(X => x.MapKey(“idProject”);特别是如果孩子将有一个参考实体父 –

+0

感谢,@StevePy你!右键'ProjectWO'代表一个链接表,现在我已经删除了复合键并且只保留了FK,并且我在哪里放置了这个.Map(x => x.MapKey(“idProject”));?当我尝试它说“没有MapKey的定义...” – Jalle

回答

0

关于映射键...这涉及到EF 6,看来EF Core不具备此功能,所以我也不太清楚如何定义的关系,而不FK属性。 (因此,为什么我倾向于避免前沿技术,直到每个人都已经变得血肉模糊,并在作者尖叫,使其可用:)

考虑下列实体:

public class Project 
{ 
    public int IdProject { get; set; } 
    public virtual List<ProjectWorkOrder> WorkOrders { get; set; } 
    ... 
} 

public class ProjectWorkOrder 
{ 
    public int IdProjectWO { get; set; } 
    public virtual Project { get; set; } 
    public virtual WorkOrder {get; set; } 
    ... 
} 

public class WorkOrder 
{ 
    public int IdWorkOrder { get; set; } 
    public virtual List<ProjectWorkOrder> Projects { get; set; } 
    ... 
} 

映射键会去项目实体配置:

public class ProjectConfiguration : EntityTypeConfiguration<Project> 
{ 
    public ProjectConfiguration() 
    { 
     ToTable("projects"); 
     HasKey(x => x.IdProject) 
     .Property(x => x.IdProject) 
     .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

     .HasMany(x => x.WorkOrders) 
     .WithRequired(x => x.Project) 
     .Map(x => x.MapKey("idProject") 
     .WillCascadeOnDelete(true); 


public class ProjectWorkOrderConfiguration : EntityTypeConfiguration<ProjectWorkOrder> 
{ 
    public ProjectWorkOrderConfiguration() 
    { 
     ToTable("project_workorders"); 
     HasKey(x=> x.IdProjectWO) 
     Property(x => x.idProjectWO) 
     .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

     HasRequired(x => x.Project) 
     .WithMany(x => x.WorkOrders) 
     .WillCascadeOnDelete(false); 
     HasRequired(x => x.WorkOrder) 
     .WithMany(x => x.Projects) 
     .WillCascadeOnDelete(false); 
    } 
} 

通过讲述的FK列EF您删除需要在实体声明FK值。对于实体,我建议使用参考成员(即ProjectWorkOrder中的项目参考)或FK字段,或者都不要;但不是参考和FK。这是因为,如果同时具有引用和FK,那么在将代码保存到实体时,这可能会导致代码和EF内的混淆。如果我设置ID为1的实体实例的引用,但可以将FK字段设置为“2”,那么我该如何信任EF来执行此操作?通常为了避免这种怪异现象,您需要向设置者添加代码,以确保引用和FK永远不会设置为不同的值。因此,如果您使用EF Core,那么这可能是您需要考虑的路线,除非有人知道如何使用.HasForeignKey或类似方法来处理模式而不是实体。

无论我添加引用回到父母会依靠什么实体作为我的系统中的顶级。例如,如果我总是处理项目并希望获得相关的工作订单,并且不需要从工作订单返回到项目,那么我的ProjectWorkOrder实体不会打扰您有Project或ProjectId,Project只会注册一个。的hasMany(X => x.WorkOrders).MAP(X => x.MapKey(“idProject”)WithRequired();如果我从工单到项目,然后我不得不导航性能在某些情况下,我不关心实体细节,只关联(即查找),那么在这些情况下,我只需要映射FK。通常这些将与枚举或名称 - 值对相关联。此示例假定双向导航。