如何表示与实体框架的一对多关系?

时间:2013-10-20 07:47:27

标签: c# sql entity-framework

如何使用实体框架表示ASP.NET MVC中的一对多关系?

我的项目是一个电话会议项目。我有一个Conferences的数据库。每个虚拟Conference会议室都有TitleOwnerName和不同DialInNumbers的列表。我知道为了建立一个Conference到多个DialInNumbers的关系,我至少需要两个表:一个用于Conferences,一个用于DialInNumbers } 至少。我在创建,修改和访问DialInNumbers时遇到了问题。我的代码肯定缺少一些东西。我们来看看:

以下是Conference的模型:

public class Conference
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string OwnerName { get; set; }
    public List<string> DialInNumbers { get; set; }
}

该模型需要DbContext(不确定为什么......)

public class ConferenceDbContext : DbContext
{
    public DbSet<Conference> Conferences { get; set; }
}

然后,在ControllerConferenceController)中,我们可以CreateEdit一个Conference。例如:

public ActionResult Create(Conference conference)
{
    if (ModelState.IsValid)
    {
        conference.DialInNumbers = ThreeRandomlyGeneratedPhoneNumbers(); 

        db.Conferences.Add(conference);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(conference);
}

当我保存数据库更改时,我只获得Conferences的一个表。如何获取多个表以及如何在实体框架中将它们链接在一起?

谢谢。

2 个答案:

答案 0 :(得分:4)

您无法在实体和字符串之间定义1:N关系。在EF中,只能在两个实体之间建立关系,因此DialInNumber应该由实体表示。

public class DialInNumber {
   public int ID { get; set; }
   public string Number { get; set; }
   public virtual Conference Conference { get; set;}
}

Conference类应该引用这些实体的集合而不是字符串集合。

public class Conference {
    public string Title { get; set; }
    public string OwnerName { get; set; }
    public virtual ICollection<DialInNumber> DialInNumbers { get; set; }    
}

并注意:为了使延迟加载工作,DialInNumbers属性应该是虚拟的

答案 1 :(得分:0)

public class Conference
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string OwnerName { get; set; }
    public List<string> DialInNumbers { get; set; }
}

您的实体只有标量属性。这意味着它不涉及另一个实体。在您的特定情况下,属性DialInNumbers是一个字符串列表,它不是实体列表。实体框架将导航属性导入到表关系中,而现在情况并非如此。

如果你想要一个DialInNumbers表,你需要有一个DialNumber列表。

public class Conference
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string OwnerName { get; set; }
    public List<DialNumber> DialInNumbers { get; set; }
}

public Class DialNumber
{
    public string Number{get;set;}
    public int ConferenceId{get;set;}
    public Conference Conference{get;set;}
}

您需要在配置类中为导航属性配置实体。

modelBuilder
   .Entity<DialNumber>()
   .HasRequired(p => p.Conference);

如果您想使用具有ID的实体,则需要将DialNumber修改为:

public Class DialNumber
{
    public string Number{get;set;}
    public Conference Conference{get;set;}
}

modelBuilder
   .Entity<DialNumber>()
   .HasRequired(p => p.Conference);
   .WithMany(b => b.DialNumber)
   .HasForeignKey(p => p.ConferenceId);

这将允许您稍后减少附加实体的开销,并允许您以您想要的方式命名外键,在本例中为ConferenceId,而不是将产生的默认语法(如第一种情况) )“Conference_Id”。