我有一個使用 ASP.NET Core、Angular、EF Core、SQL Server、AutoMapper 和存盤庫模式的繪畫 Web 應用程式。
問題是當我嘗試從繪畫表中更新單個繪畫時,它不會保存到資料庫中。我以同樣的方法嘗試了其他表,以查看是否是流程問題,但它們成功保存。
通過招搖我呼叫 put 方法,這呼叫了繪畫控制器,進入存盤庫,存盤庫回傳更新的物件但是當我去資料庫時沒有更新。如果我從 swagger 中呼叫 get 操作,我也看不到更新。
當我添加斷點以查看資料時,從頭到尾一切看??起來都很好,但它只是沒有保存到資料庫中。為了測驗,我什至嘗試洗掉自動映射器邏輯并在更新方法中手動創建一個物件,并將現有物件屬性設定為這些硬編碼值,以查看它是傳入資料,但仍然沒有運氣。同樣,為了測驗,我嘗試更新其他表并且這些表有效。
控制器
[HttpPut("{paintingId:int}")]
public async Task<IActionResult> UpdatePaintingAsync(int paintingId, [FromBody] UpdatePaintingRequest updatePaintingRequest)
{
try
{
if (await repository.Exists(paintingId))
{
var updatedPaiting = await repository.UpdatePainting(paintingId, mapper.Map<DataModels.Painting>(updatePaintingRequest));
if (updatedPaiting != null)
{
return Ok(updatePaintingRequest);
}
}
return NotFound();
}
catch (Exception ex)
{
logger.LogError($"Failed to update painting: {ex}");
return BadRequest("Failed to update painting");
}
}
從存盤庫更新方法
public async Task<Painting> UpdatePainting(int paintingId, Painting request)
{
var existingPainting = await GetPaintingByIdAsync(paintingId);
if (existingPainting != null)
{
existingPainting.Name = request.Name;
existingPainting.Description = request.Description;
existingPainting.ImageUrl = request.ImageUrl;
existingPainting.IsOriginalAvailable = request.IsOriginalAvailable;
existingPainting.IsPrintAvailable = request.IsPrintAvailable;
existingPainting.IsActive = request.IsActive;
await context.SaveChangesAsync();
return existingPainting;
}
return null;
}
獲取繪畫以更新
public async Task<Painting> GetPaintingByIdAsync(int paintingId)
{
return await context.Painting
.Include(x => x.PaintingCategories)
.ThenInclude(c => c.Category)
.AsNoTracking()
.Where(x => x.PaintingId == paintingId)
.FirstOrDefaultAsync();
}
模型(在 DAO 和 DTO 上完全相同)
public class Painting
{
public int PaintingId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
public bool IsOriginalAvailable { get; set; }
public bool IsPrintAvailable { get; set; }
public bool IsActive { get; set; }
public ICollection<PaintingCategory> PaintingCategories { get; set; }
}
語境
public class JonathanKrownContext : DbContext
{
public JonathanKrownContext(DbContextOptions<JonathanKrownContext> options) : base(options)
{
}
public DbSet<Painting> Painting { get; set; }
}
模型構建器物體
modelBuilder.Entity("JonathanKrownArt.API.DataModels.Painting", b =>
{
b.Property<int>("PaintingId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<string>("ImageUrl")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsActive")
.HasColumnType("bit");
b.Property<bool>("IsOriginalAvailable")
.HasColumnType("bit");
b.Property<bool>("IsPrintAvailable")
.HasColumnType("bit");
b.Property<string>("Name")
.HasColumnType("nvarchar(max)");
b.HasKey("PaintingId");
b.ToTable("Painting");
});
uj5u.com熱心網友回復:
您的問題是您在獲取物體時使用了 AsNoTracking,因此背景關系不再跟蹤更改。因此,您需要在保存或洗掉 AsNoTracking 之前附加它。
如果您不想附加物體,則需要將 GetPaintingByIdAsync 更改為:
public async Task<Painting> GetPaintingByIdAsync(int paintingId)
{
return await context.Painting
.Include(x => x.PaintingCategories)
.ThenInclude(c => c.Category)
.Where(x => x.PaintingId == paintingId)
.FirstOrDefaultAsync();
}
如果要保留 AsNoTracking,則需要在 UpdatePainting 中添加:
context.Painting.Update(existingPainting);
在你呼叫保存之前。
更新方法執行以下操作:
開始跟蹤處于 Modified 狀態的給定物體,以便在呼叫 SaveChanges() 時在資料庫中更新它。
因此,將您的方法更改為:
public async Task<Painting> UpdatePainting(int paintingId, Painting request)
{
var existingPainting = await GetPaintingByIdAsync(paintingId);
if (existingPainting != null)
{
existingPainting.Name = request.Name;
existingPainting.Description = request.Description;
existingPainting.ImageUrl = request.ImageUrl;
existingPainting.IsOriginalAvailable = request.IsOriginalAvailable;
existingPainting.IsPrintAvailable = request.IsPrintAvailable;
existingPainting.IsActive = request.IsActive;
context.Painting.Update(existingPainting);
await context.SaveChangesAsync();
return existingPainting;
}
return null;
}
uj5u.com熱心網友回復:
我認為 usingAsNoTracking()是一種很好的做法,您應該盡可能地使用它,但是如果Update您需要將物體附加到背景關系中,這EF將知道該物體應該被更新。
因此,為了解決您的問題,只需在代碼中添加一行,如下所示:
//other lines
context.Attach(existingPainting); //<--- by this line you tell EF to track the entity
context.Painting.Update(existingPainting);
await context.SaveChangesAsync();
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/470987.html
標籤:sql服务器 asp.net 核心 .net-core 实体框架核心
