首页 > 解决方案 > 无法更新值:“主键”在尝试将实体状态更改为“已修改”时具有临时值

问题描述

这是我的第一个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:实体类型“Director”上的属性“DirectorId”在尝试将实体的状态更改为“已修改”时具有临时值。显式设置永久值或确保将数据库配置为为此属性生成值。

我在索引页面中使用这行代码导航到编辑页面:

<a asp-page="./../Movies/Create" asp-route-DirectorId="@item.DirectorId">Add Movie</a>

索引页照片: 请点击查看照片


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);
    }
}

显然,Something 扰乱了这条线:

_context.Attach(Director).State = EntityState.Modified;

正如错误所暗示的那样,也许它与主键(DirectorId)有关。

编辑页面截图: 请点击查看编辑页面


编辑.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");
        }


    }

感谢您的阅读和任何帮助。

标签: c#asp.netasp.net-coreentity-framework-core

解决方案


尝试从以下位置删除私人二传手:

public int DirectorId { get; private set; }

相反,它应该如下所示:

public int DirectorId { get; set; }

推荐阅读