简体   繁体   English

与子记录一起更新父记录 - 实体框架核心

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM