【问题标题】:Using ASP.Net and Entity Framework: adding a child object in a 1:1 relationship使用 ASP.Net 和 Entity Framework:以 1:1 的关系添加子对象
【发布时间】:2012-01-12 23:43:24
【问题描述】:

这可能是我的懒惰,但我找不到一个简单的例子。

参考我最喜欢的电视剧《权力的游戏》,我的例子如下:

Table Throne (ThroneID)
Table King (ThroneID)

使用 Entity Framework 4,我有两个彼此具有 1:1 关系的表。在代码中,我想将国王与王座相关联。一个王座可以关联 0 或 1 个国王。如果是 1:Many,我有 Add() 方法来创建关联。 1:1 用什么?

(好吧,我现在意识到我的例子不是最好的......但在这个例子中,KingID 将与 ThroneID 相同以强制执行 1:1)

GameOfThronesContext context = new GameOfThronesContext();
Throne t = new Throne();
King k = new King();
t.Kings.Add(k);  // doesn't work because "Add" isn't available
context.Thrones.AddObject(t);

【问题讨论】:

  • 看起来我回答了我自己的问题。我不确定在保存时是否会保持关联,但我对其进行了测试并且以下工作。您必须将父级分配给子级,而不是相反。这一定会导致框架将 King 添加为 Throne 的子项,但这并不明显。我可能仍然错过了另一个方向的等效分配,但我无法弄清楚。如果有人可以确认或否认,我将不胜感激。

标签: c# asp.net entity-framework entity-framework-4


【解决方案1】:

如果对于EF Code First 4.1,下面的解决方案展示了如何设计两个类以实现一对零/一的关系,结果将是:

  • 王座{Id(PK), Name..}
  • 国王 {Id(PK,FK), Name..}



public class Throne { public int Id { get; set; } public string Name { get; set; } public virtual King King { get; set; } }

public class King
{
    public int Id { get; set; }
    public virtual Throne Throne { get; set; }
    public string Name { get; set; }
}

然后在上下文的 OnModelCreating 或配置类中定义关系:


public class MyContext : DbContext
{
    public DbSet< Throne> Thrones { get; set; }
    public DbSet< King> Kings { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
//We define the key for the King table modelBuilder.Entity< King>().HasRequired(x => x.Throne); } }

然后您可以:

 var throne = new Throne(){Name = "First Throne"};
 var king = new King() { Name = "First King" };
 throne.King = king;
 context.Thrones.Add(throne);
 context.SaveChanges();

【讨论】:

  • 感谢您为回答问题所做的努力,但不幸的是,您对答案的框架对我没有帮助。我一直在寻找 MS 如何基于数据模型 (edmx) 设置业务层对象的答案,并且我设法回答了我自己的问题。随着我对它的使用越来越熟悉,我知道我还有很多东西要学。
  • 实际上,重新阅读您的解决方案,我第一次阅读时并没有真正理解它。所以这增强了模型,所以我可以按照我最初打算的方式使用模型 - 一个更好的解决方案,从长远来看可能需要更多的维护。是否有一个功能选项可供选择,以便框架在不手动添加的情况下生成它?
  • 上面的代码首先使用 Ef 代码:首先创建模型,然后创建数据库,这与使用 edmx 从 db 模式生成的类相反。在线查看一些文档,这是一个好的开始:weblogs.asp.net/scottgu/archive/2010/07/16/…
【解决方案2】:

更新以反映 OP 的 cmets:

var t = new Throne {
    Id = Guid.NewGuid(),
    //...
    King = new King {
        Id = Guid.NewGuid()
        //...
    }
};

context.Thrones.Add(t);
context.SaveChanges();

EF 4.1 足够聪明,可以解决约束。

【讨论】:

  • 我的例子不是最好的,但这个解决方案会违反关键约束。国王是王座的孩子。 ThroneID 必须首先存在。此外,此解决方案需要调用 SaveChanges 两次,我可以这样做,但我确信该框架将允许您只需要调用一次的过程。我想知道如何实现这一目标。
【解决方案3】:

所以我回答了我自己的问题:MS 安排它,以便在这种情况下您必须将父母分配给孩子。由于某种原因,从数据实体框架生成的代码无法创建将子级分配给父级的能力。我花了一段时间才找到它。以下作品:

GameOfThronesContext context = new GameOfThronesContext();
Throne t = new Throne();
King k = new King();
//t.Kings.Add(k);  // doesn't work because "Add" isn't available
k.Throne = t;  // this is made available by the framework
context.Thrones.AddObject(t);

话虽如此,george2giga 展示了如何增强模型,以便您可以将子代添加到父代(我认为),这样您就可以按照我最初想要的方式使用 t.King = k;,这是一个更好的方法解决方案。赞一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多