我有两个表,Promotion和PromotionLine,外键定义为PromotionLine.PromoID = Promotion.ID
PromotionLines与Promotion模型相关联,Promotion类中包含以下内容:
public IList<PromotionLine> PromotionLineItems { get; set; }
我选择不使用虚拟广告,因为如果我们只是使用摘要视图来显示高级促销信息(例如促销列表),我就不想加载宣传线。
当需要推广详情时,我会获得推广热线:
public static Promotion GetInstance(int? promotionId)
{
if (promotionId == null) return null;
using (APP01Entities entities = new APP01Entities())
{
return entities.Promotions
.Include(s => s.PromotionState)
.Include(h => h.PromotionHeaderType)
.Include(l => l.PromotionLineItems)
.Include(c => c.PromotionComments)
.FirstOrDefault(p => p.ID == promotionId);
}
}
这很有效,我可以在我的视图中访问促销行。
但是,当我去更新更改时,我遇到错误:
“发生了参照完整性约束违规:属性 &。促销活动的价值&#39;在一段关系的一端不匹配 &lt; PromotionLine.PromotionID&#39;的属性值在另一 端“。
我理解为什么会出现这种错误。我不知道如何绕过它。 我使用默认更新方法(由EF脚手架创建):
public bool Update()
{
try
{
using (APP01Entities entities = new APP01Entities())
{
entities.Promotions.Attach(this);
var entity = entities.ChangeTracker.Entries<Promotion>().FirstOrDefault(e => e.Entity == this);
if (entity == null)
{
return false;
}
entity.State = EntityState.Modified;
entities.SaveChanges();
}
return true;
}
catch (System.Data.Entity.Validation.DbEntityValidationException e)
{
throw e.Improve();
}
}
问题在于:
entities.Promotions.Attach(this);
&#34;这&#34;有促销线。 entities.Promotions没有。
以下是我调用更新方法的方法:
[HttpPost]
public ActionResult Edit(Promotion promotion)
{
if (ModelState.IsValid)
{
promotion.Update();
}
return View(promotion);
}
问题
答案 0 :(得分:2)
这不是一项微不足道的任务。您需要更新对象图。换句话说,您需要更新Master-Detail。
为了使答案简单,我想我的Order
实体的OrderDetails
属性为List<OrderDetail>
。编辑时应注意:
OrderDetail
已添加到OrderDetails
,其主要标志是Id
属性等于0. OrderDetail
已被移除,OrderDetails
OrderDetail
已更改。更新Order
时,您应该更新Order
本身并应用上述更改。
<强>步骤强>
以下是步骤:
<强>代码强>
以下是代码:
public void Update(Order editedOrder)
{
var context = new YourDbContext();
//Get original order from database.
var originalOrder = context.Orders.Including("OrderDetails").Where(x => x.OrderId == editedOrder.OrderId).FirstOrDefault();
//Update the value of original order using edited order.
context.Entry(originalOrder).CurrentValues.SetValues(editedOrder);
//Find list of added items (Id of added items is 0).
var addedList = editedOrder
.OrderDetails
.Where(y => y.OrderDetailId == 0)
.ToList();
//Find list of removed items.
var deletedList = originalOrder
.OrderDetails
.Where
(
x =>
(
!editedOrder.OrderDetails
.Select(y => y.OrderDetailId)
.Contains(x.OrderDetailId)
)
)
.ToList();
//Find list of edited items.
var editedList = editedOrder.OrderDetails
.Where
(
y => originalOrder
.OrderDetails
.Select(z => z.OrderDetailId)
.Contains(y.OrderDetailId)
)
.ToList();
//Use a loop over deleted items list and set state of them to removed.
deletedList.ForEach(deletedDetail =>
{
originalOrder.OrderDetails.Remove(deletedDetail);
context.Entry(editedOrder).State = EntityState.Deleted;
});
//Use a loop over edited items list and update value of original order details that have been loaded in context.
editedList.ForEach(editedDetail =>
{
var originalOrderDetail = originalOrder.OrderDetails.Where(x => x.OrderDetailId == editedDetail.OrderDetailId).FirstOrDefault();
context.Entry(originalOrderDetail).CurrentValues.SetValues(editedDetail);
});
//Use a loop over added items list and set state of them to added.
addedList.ForEach(addedDetail =>
{
originalOrder.OrderDetails.Add(addedDetail);
});
//Set the state of original order to modified.
context.Entry(oroginalOrder).State = System.Data.Entity.EntityState.Modified;
//Save context changes.
context.SaveChanges();
}