[英]Update parent record along with child record - entity framework core
Below code updates child record or throws conflict(optimistic concurrency) if timestamp was different from original.如果时间戳与原始时间戳不同,下面的代码会更新子记录或引发冲突(乐观并发)。
Whenever we update child record, timestamp gets updated automatically.每当我们更新子记录时,时间戳都会自动更新。 I would like to update parent record's timestamp as well, while updating child record.我想更新父记录的时间戳,同时更新子记录。 This is because If I need the hierarchy locked, I need to change the timestamp of both parent and child.这是因为如果我需要锁定层次结构,我需要更改父子时间戳。 May I know how do I update the timestamp of parent.我可以知道如何更新父母的时间戳。
public async Task<ItemTable> UpdateChild(ItemTable ast)
{
var ChildRecord= await DbContext.ItemTables
.FirstOrDefaultAsync(e => e.ItemNo == ast.ItemNo ); // gets child record
// Below two lines to get parent record whose timestamp need to be updated
var ParentItemNo = GetSuperiorSerialNo(ast.ItemNo ); // finds parentItemNo of child
var ParentRecord = await DbContext.ItemTables // gets parent record
.FirstOrDefaultAsync(e => e.ItemNo == ParentItemNo );
if (ChildRecord!= null)
{
ChildRecord.ItemNo = ast.ItemNo ;
ChildRecord.ParentItemNo = ast.ParentItemNo ;
// How do I update the timestamp of parent? can I do manually?
// ParentRecord.Timestamp = new byte[] { 0, 0, 0, 0, 0, 0, 0, 120 };
try
{
//If value in the rowversion(timestamp) column is different than the original value, then catch gets called
// Or child record gets updated (along with the timestamp column)
DbContext.SaveChanges();
return ChildRecord;
}
catch (DbUpdateConcurrencyException ex)
{
var entry = ex.Entries.Single();
var clientValues = (ItemTable)entry.Entity;
var databaseEntry = entry.GetDatabaseValues();
var databaseValues = (ItemTable)databaseEntry.ToObject();
if (databaseValues.Status != clientValues.Status)
return StatusCode(409); // throw conflict
}
}
return null;
}
Model:模型:
public partial class ItemTable
{
public byte[] Timestamp { get; set; }
public string ItemNo{ get; set; }
public string ParentItemno{ get; set; }
public virtual ItemTable Parent { get; set; }
public virtual ICollection<ItemTable> Children { get; set; } = new List<ItemTable>();
}
// below classes to get ItemNo of children and granchildren as a list of dictionaries while maintaining their relationship
public class GrandChild
{
public string ItemNo { get; set; }
public byte[] Timestamp { get; set; }
}
public class Child
{
public string ItemNo { get; set; }
public byte[] Timestamp { get; set; }
public IEnumerable<GrandChild> GrandChildSerialNos { get; set; }
}
If you have not too deep hierarchy, for example 6, you can load parent records via Include
.如果您没有太深的层次结构,例如 6,您可以通过Include
加载父记录。
public async Task<ItemTable> UpdateChild(ItemTable ast)
{
var ChildRecord = await DbContext.ItemTables
.Include(e => e.Parent.Parent.Parent.Parent.Parent.Parent)
.FirstOrDefaultAsync(e => e.ItemNo == ast.ItemNo); // gets child record with parents
if (ChildRecord != null)
{
ChildRecord.ItemNo = ast.ItemNo ;
ChildRecord.ParentItemNo = ast.ParentItemNo;
var parent = ChildRecord.Parent;
while (parent != null)
{
parent.Timestamp = new byte[] { 0, 0, 0, 0, 0, 0, 0, 120 };
parent = parent.Parent;
}
try
{
//If value in the rowversion(timestamp) column is different than the original value, then catch gets called
// Or child record gets updated (along with the timestamp column)
DbContext.SaveChanges();
return result;
}
catch (DbUpdateConcurrencyException ex)
{
// always return conflict
return StatusCode(409); // throw conflict
}
}
return null;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.