簡體   English   中英

與子記錄一起更新父記錄 - 實體框架核心

[英]Update parent record along with child record - entity framework core

如果時間戳與原始時間戳不同,下面的代碼會更新子記錄或引發沖突(樂觀並發)。

每當我們更新子記錄時,時間戳都會自動更新。 我想更新父記錄的時間戳,同時更新子記錄。 這是因為如果我需要鎖定層次結構,我需要更改父子時間戳。 我可以知道如何更新父母的時間戳。

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;
}

模型:

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; }
}

如果您沒有太深的層次結構,例如 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