实体框架多重关系

时间:2013-04-09 20:57:47

标签: ef-code-first

我是Entity Framework的新手,我可能有一个简单的问题。

我已经将结构简化为最清楚(我希望是)。

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

所以我想象一下这些简单的类:

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; }
}

我希望这些类产生以下数据库结构:

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)

我用modelBuilder尝试过很多东西,但我从来没有得到我想要的东西。 是否有使用Fluent API的解决方案来做我想做的事情?

非常感谢你的帮助。

2 个答案:

答案 0 :(得分: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; }
}

注意:抱歉,这是使用Property Mapping

完成的

链接Here is a link to simple Fluent Mapping example

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

答案 1 :(得分: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

相关问题