我有点奇怪的问题。我在保存与另一个实体具有*到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,如何将我的新实体添加到数据库中?
答案 0 :(得分:1)
您可以将Store
的外键ID添加到Store
实体(Equipment
),而不是加载所有equipment.StoreId
实体。
这将确保EF在不加载整个图表的情况下看到新创建的Equipment
和Store
实体之间的关系。
由于您使用的是模型第一种方法,因此您可以找到有关如何执行此操作的文档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();