我想为网站开发一个CRUD界面,我一直在Edit方法中出错

问题描述 投票:2回答:1

我得到的错误是:

UPDATE语句与FOREIGN KEY约束“FK_dbo.Albums_dbo.Artists_ArtistId”冲突。冲突发生在数据库“MusicStoreData”,表“dbo.Artists”,列“ArtistId”

它发生在HttpPost Edit操作中。

我想做的就是编辑特定的专辑。例如:有一张名为AC / DC的专辑,我希望能够编辑流派,标题,艺术家等。

我尝试更改视图并在Db中放置一个包含当前流派和艺术家的下拉列表,但后来我得到了参照完整性错误。

这是控制器:

public ActionResult Edit(int id)
{
        Album album = db.Albums.Find(id);

        return View(album);
}

[HttpPost]
public ActionResult Edit(Album album)
{
        if(ModelState.IsValid)
        {
            //Album editAlbum = db.Albums.Find(album.AlbumId);
            //album.AlbumId = editAlbum.AlbumId;
            db.Entry(album).State = EntityState.Modified;
            db.SaveChanges();
            return (RedirectToAction("Index"));
        }

        return View(album);
}

这是观点:

@model MvcMusicStore.Models.Album

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

@using (@Html.BeginForm())
{
    <fieldset>
        @Html.HiddenFor(x => x.AlbumId)
        <legend>Album</legend>

        <div>
            Genre<br />
            @Html.TextBoxFor(x => x.Genre.Name)
        </div>
        <div>
            Artist<br />
            @Html.TextBoxFor(x => x.Artist.Name)
        </div>
        <div>
            Title<br />
            @Html.EditorFor(x => x.Title)
        </div>
        <div>
            Price<br />
            @Html.TextBoxFor(x => x.Price)
        </div>
        <div>
            Description<br />
            @Html.EditorFor(x => x.Genre.Description)
        </div>

        <p><input type="submit" value="Save" /></p>
    </fieldset>
}

<div>@Html.ActionLink("Return to List", "Index")</div>

这些是模型类:

namespace MvcMusicStore.Models
{
    public class Album
    {
        public int AlbumId { get; set; }
        public int GenreId { get; set; }
        public int ArtistId { get; set; }
        public virtual Genre Genre { get; set; }
        public string Title { get; set; }
        public decimal Price { get; set; }
        public virtual Artist Artist { get; set; }
    }

    public class Genre
    {
        public int GenreId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public List<Album> Albums { get; set; }
    }

    public class Artist
    {
        public int ArtistId { get; set; }
        public string Name { get; set; }
    }
}

和DbContext:

namespace MvcMusicStore.Models
{
    public class MusicStoreEntities : DbContext
    {
        public DbSet<Album> Albums { get; set; }
        public DbSet<Genre> Genres { get; set; }
        public DbSet<Artist> Artists { get; set; }
    }
}

我知道我错过了一些东西,但我真的不能把手指放在上面。如果有人愿意帮助我,我会很高兴。谢谢!

c# html asp.net
1个回答
3
投票

您可以通过以下两种方式解决:

1.简单的方法和不完整的方式 - 只是为了摆脱这个错误

只需添加:

 @Html.HiddenFor(x => x.ArtistId)

到你的表格。您的请求是无状态的,因此服务器只是被发送到您的表单中包含的内容。然而,这会使您无法使用其中一个文本框更改您的艺术家(但这也无法使用,我将在第二个选项中触摸)。

2.稍微好一些的方式

现在,您正在向控制器发布与您的模型不匹配的数据。你的控制器期待一个Album类型的对象,你发布的东西像Genre.NameAlbum没有。因此,您的控制器将默认使用0作为这些对象的外键(这就是您现在面临的问题)。我建议创建一个名为AlbumEditViewModel的新类,其中包含GenreNameArtistName的文本字段(您可能希望从此视图中删除Genre.Description,因为我认为您不想编辑它)。在此视图的get方法中,使用给定相册的适当值水合ViewModel,然后将其发送到视图。在你的post方法中,你将从数据库中获得基于AlbumAlbum.AlbumId模型,并获得GenreArtist的ID,然后在保存Album之前设置你的Album模型的ID。

其他建议

我可能会将此更改为下拉菜单而不是文本框,因为它现在需要完全匹配才能获得艺术家ID。或者,您可以将其保留为文本框,让控制器检查艺术家是否存在这样的名称,如果不存在,则在分配ID之前,使用该名称在数据库中创建新的艺术家。

如果您有疑问,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.