C# 实体框架-保存父实体时未将新子实体添加到数据库(仅在生产环境中)
我在申请中遇到了一个奇怪的问题。我有以下更新父实体和添加新子实体的代码C# 实体框架-保存父实体时未将新子实体添加到数据库(仅在生产环境中),c#,sql-server,entity-framework,linq,C#,Sql Server,Entity Framework,Linq,我在申请中遇到了一个奇怪的问题。我有以下更新父实体和添加新子实体的代码 Item item = db.Items.Find(Id); if (newSubItems.Count() > 0) { newSubItems.ForEach(x => { var subItem = new SubItem(); subItem.Name = x.Name; i
Item item = db.Items.Find(Id);
if (newSubItems.Count() > 0)
{
newSubItems.ForEach(x =>
{
var subItem = new SubItem();
subItem.Name = x.Name;
item.SubItems.Add(subItem);
});
}
item.ModifiedAt = DateTime.Now;
item.ModifiedBy = UserId;
db.Entry(item).State = EntityState.Modified;
using (var s = db.Database.BeginTransaction(isolationLevel: IsolationLevel.RepeatableRead))
{
await db.SaveChangesAsync();
s.Commit();
logger.info("Updated successfully.");
}
此代码在我的本地环境中运行良好。如果我提供了新的子项,这些子项将成功添加到相应的表中
模型如下所示
public partial class Item
{
public Item()
{
this.SubItems = new HashSet<SubItem>();
}
public int Id { get; set; }
public DateTime ModifiedAt { get; set; }
public int ModifiedBy { get; set; }
public virtual ICollection<SubItem> SubItems { get; set; }
}
public partial class SubItem
{
public int Id { get; set; }
public string Name { get; set; }
public int ItemId { get; set; }
public Item Item { get; set; }
}
现在查看生产环境中的日志,我可以看到消息“Sub items not added for Id”被多次记录,并且在第二次保存操作中成功添加了Sub items
想知道是否有人知道仅在特定环境中这种奇怪行为的原因。在第一种方法中,在对其执行
item.SubItems.Add()
之前,您应该检查item.SubItems
是否为null
如果为空,则初始化,如item.SubItems=new ICollection()代码>
在第二种方法中,在这个代码块中,您没有分配ItemId
newSubItems.ForEach(x =>
{
var subItem = new SubItem();
subItem.Name = x.Name;
subItem.ItemId = item.Id;/* missing line*/
db.SubItems.Add(subItem);
});
谢谢你的回复。我的第二种方法对我来说效果不错。您是对的,我遗漏了一行subItem.ItemId=item.Id代码>。我已经更新了这个问题。现在进入第一种方法。如果该值像您所说的那样为null,那么当我尝试使用db.SubItems.add(subItem)向其添加项时,它不应该抛出NullReferenceException
代码>?@Manu我想知道,在子项类中的三个属性中,您只指定了名称。原始代码中的ItemId属性如何?Id
是一个自动递增的标识元素。我相信不需要显式指定ItemId
,因为我正在将subitem对象添加到item对象的子集合中。我想这种关系应该由实体框架自动解决。最重要的是,此代码在我的本地环境中运行良好。当您获得项目详细信息item item=db.Items.Find(Id)时,尝试包含子项目(使用.Include)代码>使用Item Item=db.Items.Include(i=>i.SubItems)。其中(i=>i.Id==Id)代码>您可能也不需要db.Entry(item).State=EntityState.Modified代码>由于您未处于分离模式(除非您已明确禁用更改跟踪)@Developer感谢您的建议。我认为,默认情况下,应该加载所有子实体,并且仅当我手动禁用LazyLoadingEnabled
属性时,才需要.Include
。我将尝试按照您的建议删除将状态更新为modified
的第二条语句,但我仍然不确定该语句是否会导致类似的问题。请检查是否在生产数据库中正确设置了外键关系?此外,在子项
实体中,缺少项
的导航属性,以使EF了解项外键-不确定是否已使用fluent设置它syntax@DeveloperFK关系在生产中是正确的。我甚至在我的开发环境中尝试了生产数据库拷贝,它工作得很好。在这里添加示例模型时,我忽略了导航属性。现在更正它。
newSubItems.ForEach(x =>
{
var subItem = new SubItem();
subItem.Name = x.Name;
subItem.ItemId = item.Id;/* missing line*/
db.SubItems.Add(subItem);
});