C# 与联接(桥接)表的一对多关系
我正在尝试实现以下模型: 我有一个字典表(C# 与联接(桥接)表的一对多关系,c#,database,entity-framework,ef-code-first,C#,Database,Entity Framework,Ef Code First,我正在尝试实现以下模型: 我有一个字典表(ProductOffertable),其中包含一些记录(就像可编辑枚举一样)。另外,我还有一个主表(ChangeNet),它应该存储ProductOffer的集合。字典不应该有主表的外键,因此我决定创建包含两个表的外键的附加表changenetoproductoffer ChangeNet table CNtoPO table ProductOffer table (dictionary) --------
ProductOffer
table),其中包含一些记录(就像可编辑枚举一样)。另外,我还有一个主表(ChangeNet
),它应该存储ProductOffer
的集合。字典不应该有主表的外键,因此我决定创建包含两个表的外键的附加表changenetoproductoffer
ChangeNet table CNtoPO table ProductOffer table (dictionary)
-------- ------------ --------
CNId ---> CNId ---> POId
name POId Name
方案:
型号:
控制器:
[HttpPut]
[Route("api/cn/update")]
public IHttpActionResult Update(ChangeNetEditViewModelBase modelBase)
{
if (!ModelState.IsValid) return Ok(new ApiResultError("Object not valid for ChangeNet"));
var item = Update(modelBase);
if (item != null && item.Id > 0)
return Ok(new ApiResultSuccess<ChangeNet>(item, "ChangeNet successfully updated"));
return Ok(new ApiResultError("Can't update ChangeNet"));
}
public ChangeNet Update(ChangeNetEditViewModelBase modelBase) {
try {
var items = _context.ChangeNets.Include(x => x.ProductOffers.Select(p=>p.ProductOffer));
var changeNet = items.FirstOrDefault(o => o.Id == modelBase.Id);
if (changeNet == null) return null;
Mapper.Map(modelBase, changeNet); //copy properties
changeNet.name = "test";
_context.SaveChanges(); // I GET AN ERROR HERE
return changeNet;
}
catch (Exception exception) {
_logger.Error(exception);
return null;
}
}
但我不喜欢这个解决方案。我希望EF完成所有工作(检查更改和更新、删除或添加记录)多亏了Ivan Stoyev,我才能够解决我的问题。问题与
Mapper.map
有关。它以错误的方式复制属性。因此,我需要直接分配changeNet.ProductOffers
属性
public ChangeNet Update(ChangeNetEditViewModelBase modelBase) {
try {
var items = _context.ChangeNets.Include(x => x.ProductOffers.Select(p=>p.ProductOffer));
var changeNet = items.FirstOrDefault(o => o.Id == modelBase.Id);
if (changeNet == null) return null;
Mapper.Map(modelBase, changeNet); //IT COPIES NESTED PROPS IN WRONG WAY!!!
changeNet.name = "test";
changeNet.ProductOffers = modelBase.ProductOffers; //ASSIGN DIRECTLY!!!
_context.SaveChanges();
return changeNet;
}
catch (Exception exception) {
_logger.Error(exception);
return null;
}
}
现在它就像一个符咒 插入数据时,CnToPo中是否有任何一行显示ChangeNet和ProductOffer之间的关系?@IkramTurgunbaev,是的。为什么不在
ChangeNetTopProductOffer
中设置一个Id
列,并将其设置为主键?模型看起来不错。为了告诉您出了什么问题,我们需要查看失败的代码。@AbdulSamad,在这种情况下,它只插入新记录,而不进行更新和删除
[HttpPut]
[Route("api/cn/update")]
public IHttpActionResult Update(ChangeNetEditViewModelBase modelBase)
{
if (!ModelState.IsValid) return Ok(new ApiResultError("Object not valid for ChangeNet"));
var item = Update(modelBase);
if (item != null && item.Id > 0)
return Ok(new ApiResultSuccess<ChangeNet>(item, "ChangeNet successfully updated"));
return Ok(new ApiResultError("Can't update ChangeNet"));
}
public ChangeNet Update(ChangeNetEditViewModelBase modelBase) {
try {
var items = _context.ChangeNets.Include(x => x.ProductOffers.Select(p=>p.ProductOffer));
var changeNet = items.FirstOrDefault(o => o.Id == modelBase.Id);
if (changeNet == null) return null;
Mapper.Map(modelBase, changeNet); //copy properties
changeNet.name = "test";
_context.SaveChanges(); // I GET AN ERROR HERE
return changeNet;
}
catch (Exception exception) {
_logger.Error(exception);
return null;
}
}
private void RemoveProductOffersFromChangeNet(int changeNetId)
{
//Remove all ProductOffers related to the current ChangeNet
var itemsToDelete = _context.ChangeNetToProductOffers.Where(po => po.ChangeNetId == changeNetId);
foreach (var item in itemsToDelete) _context.ChangeNetToProductOffers.Remove(item);
}
public ChangeNet Update(ChangeNetEditViewModelBase modelBase) {
//some code
RemoveProductOffersFromChangeNet(changeNet.Id);
_context.SaveChanges();
return changeNet;
}
public ChangeNet Update(ChangeNetEditViewModelBase modelBase) {
try {
var items = _context.ChangeNets.Include(x => x.ProductOffers.Select(p=>p.ProductOffer));
var changeNet = items.FirstOrDefault(o => o.Id == modelBase.Id);
if (changeNet == null) return null;
Mapper.Map(modelBase, changeNet); //IT COPIES NESTED PROPS IN WRONG WAY!!!
changeNet.name = "test";
changeNet.ProductOffers = modelBase.ProductOffers; //ASSIGN DIRECTLY!!!
_context.SaveChanges();
return changeNet;
}
catch (Exception exception) {
_logger.Error(exception);
return null;
}
}