2013-04-09 132 views
1

我是新来的实体框架,我可能有一个简单的问题。实体框架多重关系

我简化了结构,最大限度地清楚(我希望我是)。

想象一下,我只需要创建一个简单的“企业”类,只有一个名称。 然后另一个类名为“工人”,也只是一个工人的名字。 工人应属于企业。 企业必须有一个经理(谁是一名工人)。

因此,这里是我所想象这些简单的类:

public class Worker 
{ 
    public int WorkerId { get; set; } 
    public String Name { get; set; } 

    public int EnterpriseId { get; set; } // ForeignKey for Enterprise 
    public Enterprise Enterprise { get; set; } 
} 

public class Enterprise 
{ 
    public int EnterpriseId { get; set; } 
    public String Name { get; set; } 

    public Worker Manager { get; set; } 
    public List<Worker> Workers { get; set; } 
} 

我想这些类导致以下DB结构:

Table Worker 
    WorkerId (PK, int, not null) 
    Name (varchar(128), not null) 
    EnterpriseId (FK, int) 

Table Enterprise 
    EnterpriseId (PK, int, not null) 
    Name (varchar(128), not null) 
    Manager (FK, int) 

我试图使用模型构建器很多东西,但我从来没有得到我想要的。 有没有Fluent API的解决方案来做我想做的事情?

非常感谢您的帮助。

回答

0

你想要什么这不会让你(在Db) - 但是我建议 ...

public ICollection<Worker> Workers { get; set; } // instead of List<> 
// ... 
modelBuilder.Entity<Worker>() 
    .HasRequired(x => x.Enterprise) 
    .WithMany(x => x.Workers) 
    .HasForeignKey(x => x.EnterpriseId) 
    .WillCascadeOnDelete(false); 

modelBuilder.Entity<Enterprise>() 
    .HasOptional(x => x.Manager) 
    .WithOptionalPrincipal() // x => x.DefaultForEntity) 
    .WillCascadeOnDelete(false); 

你可以用它喜欢:

var enterprise = new Enterprise { Manager = new Worker { Name = "Manager", }, }; 
enterprise.Workers = new[] 
{ 
    enterprise.Manager, 
    new Worker{ Name = "Worker1", }, 
    new Worker{ Name = "Worker2", }, 
    new Worker{ Name = "Worker3", }, 
    new Worker{ Name = "Worker4", }, 
    new Worker{ Name = "Worker5", }, 
}; 
db.Enterprises.Add(enterprise); 
db.SaveChanges(); 
var enterprises = db.Enterprises.ToList(); 

这是你想要什么...

modelBuilder.Entity<Worker>() 
    .HasRequired(x => x.Enterprise) 
    .WithMany(x => x.Workers) 
    .HasForeignKey(x => x.EnterpriseId) 
    .WillCascadeOnDelete(false); 

modelBuilder.Entity<Enterprise>() 
    .HasKey(x => x.EnterpriseId); 

modelBuilder.Entity<Enterprise>() 
    .HasOptional(x => x.Manager) 
    .WithOptionalDependent() // x => x.DefaultForEntity) 
    .WillCascadeOnDelete(false); 

... 但不会工作 - 由于周期性参考(EF错误)。

下面是一个类似/相同的解决方案非常详细的例子...

Entity Framework One-to-Many with Default

+0

我喜欢这个网站:) 感谢你们为您解答。他们都很有趣。 我现在就研究它们,并快速回复评论。 – user2263549 2013-04-10 07:30:23

+0

这很完美。它让我完全理解它是如何工作的。 – user2263549 2013-04-10 13:01:48

+0

@ user2263549我很高兴它帮助,欢呼 – NSGaga 2013-04-10 13:02:24

0

我不知道你打算如何获得经理对象,但我的猜测是你需要使用Inheritance来使你的设计最优化。试试这个:

public abstract class Employee 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int EmployeeId{ get; set; } 

    public String Name { get; set; } 

    [ForeignKey("Enterprise"), DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int EnterpriseId { get; set; } // ForeignKey for Enterprise 

    public Enterprise Enterprise { get; set; } 
} 

[Table("Workers")] // Table per Type (TPT), This will be your Table name in your database 
public class Worker : Employee 
{ 
    //Add properties only related to workers 
} 

[Table("Managers")] // Table per Type (TPT). This will be your Table name in your database 
public class Manager : Employee 
{ 
    //Add properties only related to Managers 
} 

public class Enterprise 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int EnterpriseId { get; set; } 
    public String Name { get; set; } 

    public virtual ICollection<Employee> Employees{ get; set; } 
} 

注意Here is a link to simple Fluent Mapping example

链接:对不起,这是使用Property Mapping

链接Read about Table per Type (TPT) Inheritance here