我正在使用 VS 2022 for Mac 17.6。我当前的项目是使用 .NET 7.0 的 Razor Web 应用程序和使用 SQLite 的实体框架。
这就是我想要实现的目标:在我的数据模型中,我有两个表
EventInstance
和Note
。 EventInstance
中的几行与 Note
中的一行相关。每当用户编辑一个 EventInstance
时,对链接的 Note
的更改也应该出现在与同一行相关的所有其他 EventInstances
中。
这是我现在数据模型的一部分:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// ...
modelBuilder.Entity<EventInstance>()
.HasOne(i => i.Note)
.WithMany()
.HasForeignKey(i => i.NoteId);
}
public class EventInstance
{
public int Id { get; set; }
[Required]
[Display(Name = "Spezifikation")]
public required string Specification { get; set; }
// ...
public int? NoteId { get; set; }
[Display(Name = "Notiz")]
public Note? Note { get; set; }
// ...
}
public class Note
{
public int Id { get; set; }
[Display(Name = "Notiz"), DataType(DataType.MultilineText)]
public string? Content { get; set; }
}
在我的
Create.cshtml.cs
中,一切似乎都运行良好。我已经手动编码了这些行:
Note note = new Note() { Content = "" };
_context.Note.Add(note);
_context.SaveChanges();
int noteId = note.Id;
创建新的
EventInstance
后,我可以在数据库中检查 Event
中是否已添加新行并分配了 Id
。
这是我现有的 EditModel / PageModel for EventInstance:
public class EditModel : PageModel
{
private readonly RazorPagesSchedule.Data.ScheduleDbContext _context;
public EditModel(RazorPagesSchedule.Data.ScheduleDbContext context)
{
_context = context;
}
[BindProperty]
public EventInstance EventInstance { get; set; } = default!;
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null || _context.EventInstance == null)
{
return NotFound();
}
var eventinstance = await _context.EventInstance
.Include(i => i.EventTemplate)
.Include(i => i.ResponsiblePerson)
.Include(i => i.Note)
.FirstOrDefaultAsync(m => m.Id == id);
if (eventinstance == null)
{
return NotFound();
}
EventInstance = eventinstance;
var list = new SelectList(_context.EventTemplate, "Id", "Description").ToList();
list.Insert(0, new SelectListItem { Text = "--- Keine Aufgabenvorlage ---", Value = "" });
ViewData["EventTemplateId"] = list;
var persons = new SelectList(_context.Person.OrderBy(p => p.Sn), "Id", "Sn");
ViewData["ResponsiblePersonId"] = persons;
return Page();
}
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(EventInstance).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!EventInstanceExists(EventInstance.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool EventInstanceExists(int id)
{
return (_context.EventInstance?.Any(e => e.Id == id)).GetValueOrDefault();
}
}
预期行为:编辑事件时,注释中不会创建新行,但应更新现有链接行。
我觉得你应该从数据库加载实体并修改它,而不是从客户端逐字获取它,但它创建新注释的原因是你不告诉它它已修改。添加此:
_context.Attach(EventInstance.Note).State = EntityState.Modified;
您还需要表单中的注释 ID:
<input asp-for="@Model.EventInstance.Note.Id" hidden />
请注意,它必须是
Note.Id
而不是NoteId
,因为后者会尝试保存ID为0的注释,这通常会添加新行,但当设置为EntityState.Modified
时会崩溃。