[英]C# EF6 entity mapping
我目前正在開發一個項目(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`)
)
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
,出現錯誤:
類型'Shared.Project'上屬性'ProjectSteps'上的ForeignKeyAttribute無效。 在從屬類型“ Shared.ProjectStep”上找不到外鍵名稱“ Project”。 Name值應該是逗號分隔的外鍵屬性名稱列表。
我認為映射中存在一些問題,這是導致此錯誤的原因。 對於我的映射錯誤以及我什至使用了正確的方法,我完全是茫然。
因此,我的問題是,是否應該將DataAnnotations
與Fluent API
混合使用,有人可以幫助我正確實現此映射嗎?
請注意,這是我的第一個C#/ EF6項目,我在所有方面都不是很普通,因此歡迎您進行一些解釋。
數據注釋和流利的配置可以混合使用。 但是特別是對於關系,我發現流暢的配置更加直觀。 ForeignKey
屬性的問題在於它可以應用於FK屬性,在這種情況下,它用於指定導航屬性名稱。 或者可以將其應用於導航屬性,在這種情況下,它應包含FK 屬性名稱(或復合FK屬性名稱的逗號分隔列表)。
要知道的重要一點是,它不能用於指定FK 列名稱。 列名由Column
屬性控制,因此僅當您具有顯式FK屬性(您沒有)時才可以使用它。
Fluent API沒有這樣的限制。 你要么使用HasForeignKey
當你有明確的FK財產,或Map
與MapKey
,當你不知道。
在您的情況下,為了將您不尋常的“ Project”指定為FK列名,您可以使用以下流暢的配置(並且不要忘記從ProjectSteps
刪除無效的ForeignKey
屬性):
modelBuilder.Entity<ProjectStep>()
.HasRequired(p => p.Project)
.WithMany(s => s.ProjectSteps)
.Map(m => m.MapKey("Project"));
為了能夠向數據庫添加新的“ Project”,您需要從“ Project”類的“ 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; }
}
另外回答您的問題:
所以我的問題是,是否應該將DataAnnotations與Fluent API混合使用,有人可以幫助我正確實現此映射嗎?
混合不是一個好習慣。 Imho Fluent API總是更好,因為它提供了更多的映射選項。
有關EF映射的更多信息,請查看THIS
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.