簡體   English   中英

ASP.NET Core + Entity Framework 更改數據

[英]ASP.NET Core + Entity Framework changed data

我試圖只保存已更改的實體。

如果我刪除這個if

if (!period.IsSame(_context.Periods.First(p => p.ID == period.ID)))

一切都好。

但如果我保留它,在語句_context.Attach(period);或者如果我使用Update ,我會得到一個錯誤:

InvalidOperationException:無法跟蹤實體類型“Period”的實例,因為已跟蹤另一個具有與 {'ID'} 相同鍵值的實例。

我不知道如何測試它是否真的被修改過。

public async Task<IActionResult> OnPostAsync(List<Period> periods)
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    // _context.Periods.Add(Period);
    int i = 0;

    foreach (var period in periods)
    {
        TimeOnly startTime = TimeOnly.Parse(Request.Form["StartTime" + i].ToString());
        TimeOnly endTime = TimeOnly.Parse(Request.Form["EndTime" + i].ToString());
        period.StartHour = startTime.Hour;
        period.StartMinute = startTime.Minute;
        period.EndHour = endTime.Hour;
        period.EndMinute = endTime.Minute;
        period.StatusDate = DateTime.Now;

        // if it already exists
        if (period.ID > 0)
        {
            // if modified
            if (!period.IsSame(_context.Periods.First(p => p.ID == period.ID)))
            {
                _context.Attach(period);

                if (period.Delete)
                {
                    period.Status = (int)Status.deleted;
                }
                else
                {
                    period.Status = (int)Status.modified;
                }
            }
        }
        // if new
        else
        {
            period.Status = (int)Status.created;
            _context.Attach(period);
        }

        i++;
    }

    await _context.SaveChangesAsync();

    return RedirectToPage("./Periods");
}

我已經嘗試了更新和附加。 我搜索了實體跟蹤,但它似乎一出現在網頁上就被分離了

EF 使用更改跟蹤的概念來確定應該對實體執行的操作。 默認情況下查詢數據將導致上下文開始跟蹤它因此異常。 您可以通過默認禁用跟蹤來緩解它,例如使用.AsNoTracking()

if (!period.IsSame(_context.Periods.AsNoTracking().First(p => p.ID == period.ID)))                   
{
   // ...
}

但這不是非常可取的方法,由於多種原因——可能更改跟蹤器不會檢測到任何更改,你將需要手動處理,更大的原因——你將在循環中查詢數據庫,這對應用程序性能不利。 只需從數據庫中獲取所有內容並相應地更新它:

var existingPeriods = await _context.Periods
    .Where(p => periods.Select(p => p.ID).Contains(p.ID))
    .ToListAsync(); // or ToDictionaryAsync if there a lot of the periods

foreach (var period in periods)
{
    var existing = existingPeriods.FirstOrDefault(p => p.ID == period.ID);
    if (existing != null)
    {
        // maybe throw if period.ID != 0
        // update data in existing
        existing. ... = ...;
    }
    else
    {
        // if new ...
        _context.Periods.Add(period);
    }
    await _context.SaveChangesAsync();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM