1

我有点……奇怪的问题。保存与另一个实体具有 * 到 1 关系的新创建实体时出现错误。有点难以解释,但这是设置:

(注意:我使用的是 MVC 2 - 实体框架 4)

我的实体设置如下(为了可读性而替换了名称,但结构如所述): 我们公司有一些经理。(tblManagers) 每个经理拥有未定义数量的 Store (tblStores)。每个商店都有未定义数量的设备 (tblEquipment)。所以我的数据模型如下:

(tblManagers) 1<----->* (tblStores) 1<----->* (tblEquipment)

这个设置是有效的,因为我们已经有很多数据(来自导出旧的 Access 文件)。

在创建新设备时,您显然必须选择它所属的商店。将下拉列表中选择的值(Store 的 ID)传递给 HttpPost 方法,该方法执行以下代码:

db 是我的数据库上下文变量

myNewItem.tblStore = db.tblStores.Single(x => x.Id == store_id_from_dropdown);

db.tblEquipments.AddObject(myNewItem);

db.SaveChanges();

在我看来,这似乎是有效的代码。Resharper 没有发现任何问题,也没有编译错误(甚至警告)。但是,在运行代码时,我遇到了以下异常(在 db.SaveChanges() 上抛出):

Entities in 'CMT_DevEntities.tbl_Stores' participate 
in the 'tblManagerstblStores' relationship. 
0 related 'tblManager' were found. 
1 'tblManager' is expected.

我不知道为什么它甚至在看 tblManager 因为在我的代码中没有引用它。我知道这与经理和他们的商店之间的关系有关,但我不明白为什么

这是让我感到困惑的部分:

  • 查看 的调试值时myNewItem,我可以看到商店已添加到实体中。我什至可以检查 Store 的 tblManager 属性,它是正确的 tblManager。因此,这确认了数据库中的一切正常(如果没有经理,商店甚至都不存在)。
  • 我实际上遗漏了一些代码。设备中有一个完全相似的导航属性(假设是供应商。供应商又具有国家/地区的导航属性。关系完全相同)。我没有得到这个错误。只有商店/经理之一。

我可能遗漏了一些东西,也许是一些非常简单的东西。无论哪种方式,我都不知道为什么会这样。

所以我的问题是:给定由 MVC 中的 ModelBinder 创建的实体和导航属性的 (int) ID,我如何将新实体添加到数据库中?

4

2 回答 2

1

您可以为您的实体 ( )Store添加外键 ID,而不是加载所有实体。StoreEquipmentequipment.StoreId

这将确保 EF 在不加载整个图表的情况下看到新创建Equipment的实体与实体之间的关系。Store

由于您使用的是模型优先方法,因此您可以在 MSDN上找到有关如何执行此操作的文档。

重要的部分在注释部分:

通过清除导航属性和将外键属性添加到实体复选框,您可以选择不向关联末尾的实体添加导航属性或外键属性。如果您只添加一个导航属性,则关联将只能在一个方向上遍历。如果不添加导航属性,则必须选择添加外键属性才能访问关联末端的实体。对于多对多 ( : ) 和一对一 (1:1) 关联,您不能将外键添加到实体。有关更多信息,请参阅定义和管理关系(实体框架)。

您应该在“添加关联”对话框中检查“将外键属性添加到“设备”实体”。使用外键属性是 Entity Framework 4 中的一个新特性。它会让你的生活变得更轻松。

在这里你可以找到更详细的解释。

于 2012-08-06T11:41:00.683 回答
0

您需要正确配置实体:如果您有两个通过外键链接的实体,则需要配置导航属性。例子:

public class Destination
{
    public int DestinationId { get; set; }
    public string Name { get; set; }
    public string Country { get; set; }
    public string Description { get; set; }
    public byte[] Photo { get; set; }
    public List<Lodging> Lodgings { get; set; }
}

public class Lodging
{
     public int LodgingId { get; set; }
     public string Name { get; set; }
     public string Owner { get; set; }
     public bool IsResort { get; set; }
     public decimal MilesFromNearestAirport { get; set; }
     public int DestinationId { get; set; }
     public Destination Destination { get; set; }
}

internal class LodgingConfiguration:EntityTypeConfiguration<Charge>
{
    HasRequired(d=>d.Destination).WithMany(l=>l.Logings).HasForeignKey(d=>d.DestinationId)
}

创建日志记录类似于:

var loging = new Loging
                 {
                     ...initialize properties...
                     Destination = new Destination{..initialize destination..}
                 }
context.Add(loging);
context.SaveChanges();
于 2012-08-07T06:32:05.320 回答