C# EF6 实体映射

标签 c# .net entity-framework ef-fluent-api

我目前正在开发一个项目(WCF 服务),该项目应将 EF6 与 MySql 数据库结合使用。该部分本身已经可以正常工作,但是我在映射方面遇到了很大的问题。

我有如下 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`)
)

项目步骤表:

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时,我得到了错误:

The ForeignKeyAttribute on property 'ProjectSteps' on type 'Shared.Project' is not valid. The foreign key name 'Project' was not found on the dependent type 'Shared.ProjectStep'. The Name value should be a comma separated list of foreign key property names.

我认为我的映射存在一些问题,这是导致此错误的原因。我完全不知道我的映射在哪里出错,甚至不知道我是否使用了正确的方法。

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

请注意,这是我的第一个 C#/EF6 项目,我对所有事情都不太熟悉,因此欢迎提供一些解释。

最佳答案

数据注释和流畅的配置可以混合使用。但特别是对于关系,我发现流畅的配置更加直观。 ForeignKey 的问题attribute 是它可以应用于 FK 属性,在这种情况下它用于指定导航属性名称。或者它可以应用于导航属性,在这种情况下它应该包含 FK 属性 名称(或复合 FK 属性名称的逗号分隔列表)。

要知道的重要一点是,它不能用于指定 FK 名称。列名由 Column 控制属性,因此只有当您具有明确的 FK 属性(您没有)时才能使用它。

Fluent API 没有这样的限制。您要么使用 HasForeignKey当你有明确的 FK 属性时,或 MapMapKey当你不这样做时。

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

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

关于C# EF6 实体映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49590830/

相关文章:

c# - 将 List<double[]> 转换为 List<T>

c# - 通过 MSCOMM 将 VB6 转换为 C# 到串行端口

c# - 在 VS 2010 中为测试项目设置 useLegacyV2RuntimeActivationPolicy

c# - 无法通过将自己指定为父级来确定相关操作的有效顺序

c# - 从 EF 6.0 Beta 升级到 RC 后出现 System.MissingMethodException

c# - 如何从 WW 对象生成 CSV 文件?

c# - Linq 性能 : (ElementAt, 计数)与(foreach)

C# ref/out 参数与惰性

.net - 集中/控制.NET项目和解决方案的任意生成

c# - Entity Framework 避免延迟加载/已打开 DataReader 问题