c# - 更新实体框架中的多级属性
问题描述
我有一个具有多个属性级别的实体结构,每个头表条目都有多个子表条目,并且关系经过多个级别。表图如下所示:
我需要获取与 ECNEntries 表中的一个条目相关的所有数据以显示在网格中。用户可以在所有级别编辑条目、删除一些条目、添加更多条目。
我可以像这样获取特定条目的所有数据:
var ECNEntryInDb = ECNEntriesRepo.FindAll(f => f.ECNStages
.Select(i => i.ECNComponentDetails
.Select(j => j.ECNMaterialReferenceDetails
.Select(k => k.ECNComponentDetails))))
.Where(x => x.Id == ECNEntriesData.Id).FirstOrDefault();
但我找不到将这些数据更新回数据库的方法。
当我这样尝试时:
var xx = Mapper.Map<DAL.Entities.ECNEntries>(ECNEntriesData);
ECNEntriesRepo.Update(xx);
我遇到了一个例外:
附加类型为“ProductionControl.DAL.Entities.ECNEntries”的实体失败,因为同一类型的另一个实体已经具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。
当我尝试这个时:
var ECNEntryInDb = ECNEntriesRepo.FindAll(f => f.ECNStages
.Select(i => i.ECNComponentDetails
.Select(j => j.ECNMaterialReferenceDetails
.Select(k => k.ECNComponentDetails)))).Where(x => x.Id == ECNEntriesData.Id).FirstOrDefault();
//var ECNEntryInDb = ECNEntriesRepo.FindById(ECNEntriesData.Id);
Mapper.Map<BL.DTO.ECN.ECNEntries, DAL.Entities.ECNEntries>(ECNEntriesData, ECNEntryInDb);
ECNEntriesRepo.Update(ECNEntryInDb);
这就是我得到的:
操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。
我尝试了此页面中建议的一些解决方案,例如添加复合键等。它也没有用。给出一个例外,如:
不允许添加与处于已删除状态的实体的关系
这是示例数据结构:
"EcnEntries": [
{
"Id": 49,
"ECNHeaderId": 11,
"ECNVersionId": 8,
"ECNVersion": null,
"ECNPartNumber": "280384-01/01M",
"ECNStages": [
{
"Id": 25,
"ECNEntriesId": 49,
"OperationNo": "006",
"WorkCenterId": 198,
"ChangesRequired": "asxa",
"ReasonForChanges": "erte",
"ECNComponentDetails": [
{
"Id": 31,
"ECNStagesId": 25,
"CurrentBOMPartNumber": "jhjhk",
"ReplacementComponentPartnumber": "uyuyuy",
"ECNMaterialReferenceDetails": [
{
"Id": 38,
"ECNComponentDetailsId": 31,
"MaterialReferenceNumber": "323"
},
{
"Id": 39,
"ECNComponentDetailsId": 31,
"MaterialReferenceNumber": "12"
}
]
}
]
}
]
}
]
编辑
这就是存储库实现中的更新功能所做的。我如何也可以更改引用子表对象的状态?
public void Update(T entity)
{
contextFactory.GetDataContext().Entry(entity).State = EntityState.Modified;
}
谁能建议一种更新这些数据的方法?我是否需要遍历每个孩子并更新数据?在那种情况下,我也很困惑如何同时遍历来自 UI 的数据和来自数据库的实体以应用更改。我不确定我是否搞砸了一些非常简单的事情。
提前致谢。
解决方案
正如@jdweng 所说,问题出在Automapper 上。发现这个链接很有用。
自动映射器正在替换引用子表对象,最终将引用设置为空。它触发了错误。
推荐阅读
- kubernetes - Kubernetes - 使用 Configmap 设置环境变量组
- django - 为什么 django post 停止在 https 上工作?它通过http工作
- python - 不可能在 Odoo 11 中创建公司间交易
- c# - 使用 CredentialCache 发出 HTTP 请求并通过 AD 进行身份验证
- flutter - 仅针对一个平台的 Pubspec 依赖项
- alexa - Alexa Selected Intent 为空
- java - 替换传递依赖构建maven fat jar
- https - Spring Cloud Gateway 在启用 https 的情况下失去响应(有时)
- debian-stretch - 重新启动后,DRBD 出现已连接无盘/无盘状态
- mysql - 无法在 WSL 上安装 mysql-server