通過 Julie Lerman 的 Pluralsight 課程EF Core 6 Fundamentals 我在自己的專案中創建了兩個類(我自己的設計,但在類結構/資料層次結構方面與課程相同):
第 1 類:活動 -保存有關正在舉辦的活動(例如培訓課程)的資訊,帶有標題和描述(為簡潔起見,洗掉了一些欄位):
public class EventItem
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int EventItemId { get; set; }
[Required(AllowEmptyStrings = false)]
public string EventTitle { get; set; }
public string? EventDescription { get; set; }
[Required]
public List<EventCategory> EventCategories { get; set; } = new();
}
第 2 類:事件類別 -每個事件都可以鏈接到一個或多個預先存在的(種子)類別(例如兒童、成人)。
public class EventCategory
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int EventCategoryId { get; set; }
[Required]
public string EventCategoryName { get; set; }
public List<EventItem>? EventItems { get; set; }
}
在我創建事件的 Razor 表單中,用戶可以從多個類別中進行選擇。使用 EF Core,我獲取發布的資料(通過 VM/DTO 物件)并構造相關的父/子物體。但是,在保存到資料庫時,我得到一個例外,因為 EF Core 嘗試在它們已經存在時重新創建類別:
當 IDENTITY_INSERT 設定為 OFF 時,無法在表“EventCategories”中插入標識列的顯式值。
我的代碼明確查找用戶選擇的現有類別,但背景關系跟蹤器似乎仍然認為他們需要插入,除了創建多對多關系。
我很感激任何關于為什么會發生這種情況的意見:
using (var dbcontext = DbFactory.CreateDbContext())
{
// Get selected categories from user's check box list
var selectedCategoryIds = _eventCagetories.Where(c => c.isSelected).Select(c => c.EventCategoryId).ToList();
// Create new Event
var newEventItem = new EventFinderDomain.Models.EventItem() {
EventTitle = _eventItemDTO.EventTitle,
EventDescription = _eventItemDTO.EventDescription,
EventUrl = _eventItemDTO.EventUrl,
TicketUrl = _eventItemDTO.TicketUrl
};
// Find categories from the database based on their ID value
var selectedEventCategories = dbcontext.EventCategories.Where(c => selectedCategoryIds.Contains(c.EventCategoryId)).ToList();
// Add the categories to the event
newEventItem.EventCategories!.AddRange(selectedEventCategories);
// Add the event to the change tracker
await dbcontext.EventItems.AddAsync(newEventItem); // <-- Created correctly with child list objects added
// Detect changes for debugging
dbcontext.ChangeTracker.DetectChanges();
var debugView = dbcontext.ChangeTracker.DebugView; // <-- Incorrectly shows newEventItem.Categories being added
// Save to database
await dbcontext.SaveChangesAsync(); // <-- Cannot insert explicit value for identity column
}
事件物體似乎在除錯器中正確創建,其相關子類別包括:

但是,更改跟蹤器會錯誤地顯示已存在的所選類別再次添加:

uj5u.com熱心網友回復:
在注釋掉應用程式中的每一行代碼并重新添加直到它崩潰后,問題出現在其他地方Program.cs:
builder.Services.AddDbContextFactory<EventFinderContext>(
opt => opt.UseSqlServer(new SqlConnectionStringBuilder() {/*...*/}.ConnectionString)
.EnableSensitiveDataLogging()
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking) // <-- THE CULPRIT
);
在培訓視頻中,這種方法被描述為一種減少斷開連接的應用程式開銷的方法。我曾假設由于 HTTP 的斷開連接性質,這將是有益的,并且在創建模型的子資料時將重新建立背景關系。這對我來說是不正確的。
我應該.AsNoTracking()只在從我的資料庫中檢索只讀資料時使用。例如,為不會直接修改但用于創建多對多資料的新模型加載子資料(明確地,僅用于類別資料選項項,而不用于事件資料)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/517090.html
