【发布时间】:2020-09-06 20:27:13
【问题描述】:
这是我的第一个 ASP .Net Core 项目。它将举行董事。每个导演都有一个页面显示他/她的电影列表。
我有两节课。 电影:
public class Movie
{
public int MovieId { get; private set; }
public int DirectorId { get; set; }
[Required]
public string Title { get; set; }
public string Year { get; set; }
public string Description { get; set; }
}
还有导演:
public class Director
{
public Director()
{
Movies = new List<Movie>();
}
public int DirectorId { get; private set; }
[Required]
public string Name { get; set; }
public string Country { get; set; }
public string Bio { get; set; }
public List<Movie> Movies { get; set; }
}
但我在编辑导演时遇到了问题。当我想保存更改时,出现此错误:
InvalidOperationException:实体类型上的属性“DirectorId” 'Director' 在尝试更改 实体的状态为“已修改”。明确设置永久值 或确保将数据库配置为为此生成值 属性。
我在索引页面中使用这行代码导航到编辑页面:
<a asp-page="./../Movies/Create" asp-route-DirectorId="@item.DirectorId">Add Movie</a>
索引页面的照片: Please click to see the photo
Edit.cshtml.cs中的代码:
public class EditModel : PageModel
{
private readonly MastersOfCinema.Data.Context _context;
public EditModel(MastersOfCinema.Data.Context context)
{
_context = context;
}
[BindProperty]
public Director Director { get; set; }
public async Task<IActionResult> OnGetAsync(int? directorId)
{
if (directorId == null)
{
return NotFound();
}
Director = await _context.Director.FirstOrDefaultAsync(m => m.DirectorId == directorId);
if (Director == null)
{
return NotFound();
}
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(Director).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!DirectorExists(Director.DirectorId))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool DirectorExists(int id)
{
return _context.Director.Any(e => e.DirectorId == id);
}
}
显然,有些东西打乱了这条线:
_context.Attach(Director).State = EntityState.Modified;
可能与主键(DirectorId)有关,如错误提示。
编辑页面截图: Please Click to see Edit page
Edit.cshtml:
@page
@model MastersOfCinema.Pages.Directors.EditModel
@{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>Director</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Director.DirectorId" class="control-label"></label>
<input asp-for="Director.DirectorId" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Director.Name" class="control-label"></label>
<input asp-for="Director.Name" class="form-control" />
<span asp-validation-for="Director.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Director.Country" class="control-label"></label>
<input asp-for="Director.Country" class="form-control" />
<span asp-validation-for="Director.Country" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Director.Bio" class="control-label"></label>
<input asp-for="Director.Bio" class="form-control" />
<span asp-validation-for="Director.Bio" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="./Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
附加信息:
Context.cs(使用 EF Core):
public class Context : DbContext
{
public Context (DbContextOptions<Context> options)
: base(options)
{
}
public DbSet<MastersOfCinema.Models.Director> Director { get; set; }
public DbSet<MastersOfCinema.Models.Movie> Movie { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(
"Data Source = (localdb)\\MSSQLLocalDB; Initial Catalog = MastersOfCinama");
}
}
感谢您的阅读和任何帮助。
【问题讨论】:
-
如果你要添加一个新的,你必须使用上下文EntityState.Added,而不是Modified。如果您不添加它,请在将状态设置为已修改之前使用 Find 或其他东西从上下文中获取现有实体,或者查找其 PK 并设置它。不过我对 EF 也有点新,所以有人纠正我如果我弄错了。
-
@Nikki9696 我可以添加一个新的,它可以工作。问题在于编辑。我获取现有行,我可以看到它的值。所以我想知道为什么我点击保存按钮时会出错。看到这个:i.stack.imgur.com/pHbJb.png 无论如何我感谢你的帮助。
-
好吧,我还没有尝试过您使用 Attach 的方式,但它适用于我的小 EF 项目,我只是从上下文中获取编辑并添加到上下文中进行添加。我根本不设置状态,它知道。我使用 MyDbContext.MyEntityName.Add(object) 或 MyDbContext.MyEntityName.Find(key),设置更改和更新,然后保存更改。
-
@Nikki9696 我会再次尝试您的建议。但我对编程很陌生,恐怕我需要更精确的解决方案。再次感谢。
标签: c# asp.net asp.net-core entity-framework-core