创建新实体时出错(FK约束问题)

时间:2012-07-26 10:57:09

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

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

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

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

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

此设置有效,因为我们已经有很多数据(从导出旧的Access文件)。

创建新设备时,显然必须选择它所属的商店。在下拉列表中选择的值(商店的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。因此,这证实了数据库中的一切正常(如果他们没有经理,商店就不会存在)。
  • 我实际上遗漏了一些代码。设备中有一个完全相似的导航属性(让我们说供应商。供应商反过来又有一个国家的导航属性。关系完全相同)。虽然这个没有错误。只有商店/经理一个。

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

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

2 个答案:

答案 0 :(得分:1)

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

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

由于您使用的是模型第一种方法,因此您可以找到有关如何执行此操作的文档here on MSDN

重要的部分在注释部分:

  

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

您应该在“添加关联”对话框中选中“将外键属性添加到'设备'实体'。 使用外键属性是实体框架4中的一项新功能。它将使您的生活更轻松。

Here您可以找到更详细的解释。

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

创建Loging loks,如:

var loging = new Loging
                 {
                     ...initialize properties...
                     Destination = new Destination{..initialize destination..}
                 }
context.Add(loging);
context.SaveChanges();