C#EF6实体映射



我当前正在研究一个项目(WCF服务(,该项目应使用MySQL数据库使用EF6。那部分本身已经在工作应有的,但是我在映射方面遇到了巨大的问题。

我有3个实体,例如以下:

Employee - ManyToMany - Project - OneToMany - ProjectStep

我的数据库模型是这样的:

员工表:

CREATE TABLE `employee` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Name` varchar(255) DEFAULT NULL,
  `JobDescription` varchar(255) DEFAULT NULL,
  `Department` varchar(255) DEFAULT NULL,
  `DirectDialing` varchar(255) DEFAULT NULL,
  `Status` bit(1) DEFAULT NULL,
  PRIMARY KEY (`ID`)
)

项目表:

CREATE TABLE `project` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Titel` varchar(255) DEFAULT NULL,
  `StartDate` datetime DEFAULT NULL,
  `EndDate` datetime DEFAULT NULL,
  `Description` varchar(255) DEFAULT NULL,
  `ProjectLeader` int(11) DEFAULT NULL,
  `Status` int(11) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  CONSTRAINT `project_fk` FOREIGN KEY (`ProjectLeader`) REFERENCES `employee` (`ID`)
)

projectStep表:

CREATE TABLE `project_step` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Description` text,
  `StartDate` datetime DEFAULT NULL,
  `EndDate` datetime DEFAULT NULL,
  `Project` int(11) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  CONSTRAINT `project_step_fk` FOREIGN KEY (`Project`) REFERENCES `project` (`ID`)
)

映射表员工 - 项目

CREATE TABLE `employee_project` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `EmployeeId` int(11) DEFAULT NULL,
  `ProjectId` int(11) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  CONSTRAINT `projectId_fk` FOREIGN KEY (`ProjectId`) REFERENCES `project` (`ID`)
  CONSTRAINT `employeeId_fk` FOREIGN KEY (`EmployeeId`) REFERENCES `employee` (`ID`)
)

我然后创建了我的实体如下:

[DataContract(Namespace = "Shared")]
public class Employee
{
    public Employee()
    {
        this.Projects = new List<Project>();
    }
    [DataMember]
    [Key]
    public int ID { get; set; }
    [DataMember]
    public String Name { get; set; }
    [DataMember]
    public String Berufsbezeichnung { get; set; }
    [DataMember]
    public String Abteilung { get; set; }
    [DataMember]
    public String Durchwahl { get; set; }
    [DataMember]
    public bool Status { get; set; }
    [DataMember]
    public virtual ICollection<Project> Projects { get; set; }
}
[DataContract(Namespace = "Shared")]
public class Project
{
    public Project()
    {
        this.EmployeesWorkingOnProject = new List<Employee>();
        this.ProjectSteps = new List<ProjectStep>();
    }
    [DataMember]
    [Key]
    public int ID { get; set; }
    [DataMember]
    public String Titel { get; set; }
    [DataMember]
    public DateTime StartDatum { get; set; }
    [DataMember]
    public DateTime EndDatum { get; set; }
    [DataMember]
    public String Beschreibung { get; set; }
    [DataMember]
    [Column("Projektleiter")]
    public Employee Projektleiter { get; set; }
    [DataMember]
    public bool Status { get; set; }
    [DataMember]
    public virtual ICollection<Employee> EmployeesWorkingOnProject { get; set; }
    [DataMember]
    [ForeignKey("Project")]
    public virtual ICollection<ProjectStep> ProjectSteps { get; set; }
}
[DataContract(Namespace = "Shared")]
public class ProjectStep
{
    [DataMember]
    public int ID { get; set; }
    [DataMember]
    public String Beschreibung { get; set; }
    [DataMember]
    public DateTime StartDatum { get; set; }
    [DataMember]
    public DateTime EndDatum { get; set; }
    [DataMember]
    public Project Project { get; set; }
}

并使用Fluent API创建ManyToMany关系以及OneToMany

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("MitarbeiterID");
        m.MapRightKey("ProjektID");
        m.ToTable("mitarbeiter_projekte");
    });
    modelBuilder.Entity<ProjectStep>().HasRequired<Project>(p => p.Project).WithMany(p => p.ProjectSteps);
}

我真的很茫然,因为当我试图插入新的Project时,我会得到错误:

类型上的属性" projectSteps"上的外国基归因于 "共享"项目无效。外国关键名称"项目"不是 在依赖类型的"共享.projectStep"上找到。名称值 应该是外国关键属性名称的逗号分开列表。

我认为我的映射有一些问题,这是造成此错误的原因。对于我的映射是错误的,以及我什至使用正确的方式,我完全不知所措。

所以我的问题是,是否应该将DataAnnotationsFluent API混合,有人可以帮助我正确地映射吗?

请注意,这是我的第一个C#/EF6项目,我对所有内容都不是很常见,因此欢迎一些解释。

可以混合使用数据注释和流利的配置。但是尤其是对于关系,我发现流利的配置更加直观。ForeignKey属性的问题在于它可以应用于FK属性,在这种情况下,它用于指定导航属性名称。或可以将其应用于导航属性,在这种情况下,它应包含FK 属性名称(或Comma分离的复合FK属性名称列表(。

要知道的重要一件事是,它不能使用不能用来指定FK 名称。列名由Column属性控制,因此仅在您具有显式fk属性时才可以使用。

流利的API没有这种局限性。当您具有明确的FK属性时,您要么使用HasForeignKey,要么在不使用MapKey时使用CC_11。

在您的情况下,为了将您的异常"项目"指定为FK列名称,您可以使用以下流利的配置(并且不要忘记从ProjectSteps删除无效的ForeignKey属性(:

modelBuilder.Entity<ProjectStep>()
    .HasRequired(p => p.Project)
    .WithMany(s => s.ProjectSteps)
    .Map(m => m.MapKey("Project"));

为了能够将新"项目"添加到db,您需要从"项目"类中的" projectSteps"属性中删除外键注释。"外键"注释只能应用于不是收集类型的属性。

[DataContract(Namespace = "Shared")]
public class Project
{
    public Project()
    {
        this.EmployeesWorkingOnProject = new List<Employee>();
        this.ProjectSteps = new List<ProjectStep>();
    }
    [DataMember]
    [Key]
    public int ID { get; set; }
    [DataMember]
    public String Titel { get; set; }
    [DataMember]
    public DateTime StartDatum { get; set; }
    [DataMember]
    public DateTime EndDatum { get; set; }
    [DataMember]
    public String Beschreibung { get; set; }
    [DataMember]
    [Column("Projektleiter")]
    public Employee Projektleiter { get; set; }
    [DataMember]
    public bool Status { get; set; }
    [DataMember]
    public virtual ICollection<Employee> EmployeesWorkingOnProject { get; set; }
    [DataMember]
    public virtual ICollection<ProjectStep> ProjectSteps { get; set; }
}

在添加的问题中回答您的问题:

所以我的问题是,是否应该将数据通道与流利的API混合在一起,有人可以帮助我正确地映射吗?

混合不是一个好习惯。恕我直言流利的API总是更好,因为它提供了更多的映射选项。

有关EF映射的更多信息,请查看此

相关内容

  • 没有找到相关文章

最新更新