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);
        });