使用多个表更新异常

update exception using multiple tables

大家好,我正在尝试使用 asp.net mvc 和代码优先数据库创建一个应用程序,该数据库允许用户创建一个博客 post,其中包含尽可能多的图像 wish.I 目前正在尝试将图像路径放在一个 table 中,将标题 body 文本放在另一个 table 中,以及图像的外键 path.So我可以用多张图片创建一个 post。这是我第一次使用多个 tables,目前我在到达这一行时遇到错误 context.SaveChanges();在我尝试创建 post 并将其保存到数据库时的保存方法中。感谢您对此问题的任何帮助。

An exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in EntityFramework.dll but was not handled in user code

Additional information: An error occurred while updating the entries. See the inner exception for details

当我使用一个 table 时,我能够让程序运行,但它有这个问题:https://imgur.com/a/lQQ3Q

这是数据库图:http://imgur.com/a/iJZGx

我尝试进行但不确定在我的代码中的何处使用的查询。

var query = db.PostModel.Where(x => x.PostID == PostId).Select(x => new
{
    PostID = x.PostID,
    ImageId = x.ImageModel.ImageId,
    ImagePath = x.ImageModel.ImagePath,
    Heading = x.PostModel.Heading,
    PostBody = x.PostModel.PostBody
}).FirstOrDefault();

我的程序

查看以创建 posts

@model Crud.Models.PostModel
....
@using (Html.BeginForm("Create", "Home", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    <form action="" method="post" enctype="multipart/form-data">
        @Html.LabelFor(model => model.ImageModel.ImagePath)
        <input id="ImagePath" title="Upload a product image" multiple="multiple" type="file" name="files" />
        @Html.LabelFor(model => model.Heading)
        <input id="Heading" title="Heading" name="Heading" />
        @Html.LabelFor(model => model.PostBody)
        <input id="PostBody" title="PostBody" name="PostBody" />
        <p><input type="submit" value="Create" /></p>
    </form>
}

查看显示 posts

@model IEnumerable<Crud.Models.PostModel>
....  
@foreach (var item in Model)
{
    <div>@Html.DisplayFor(modelItem => item.Heading)</div>
    <div>@Html.DisplayFor(modelItem => item.PostBody)</div>
    <div><img class="img-thumbnail" width="150" height="150" src="/Img/@item.ImageModel.ImagePath" /></div>
}

型号

public partial class PostModel
{
    [Key]
    [HiddenInput(DisplayValue = false)]
    public int PostID { get; set; }
    public string Heading { get; set; }
    public string PostBody { get; set; }
    [ForeignKey("ImageModel")]
    public int ImageId { get; set; }
    public virtual ImageModel ImageModel { get; set; }
}

public class ImageModel
{
    [Key]
    public int ImageId { get; set; }
    public string ImagePath { get; set; }
    public string PostID { get; set; }
}

数据库上下文

public class EFDbContext : DbContext
{
    public DbSet<SchoolNewsModel> SchoolNews { get; set; }
    public DbSet<PostModel> Posts { get; set; }
    public DbSet<ImageModel> Images { get; set; }
}

控制器

public ViewResult Display()
{
    return View(repository.Posts);
}
public ViewResult Create()
{
    return View("Create", new PostModel());
}
[HttpPost]
public ActionResult Create(PostModel Image, IEnumerable<HttpPostedFileBase> files)
{
    if (ModelState.IsValid)
    {
        foreach (var file in files)
        {
            PostModel post = new PostModel();
            if (file.ContentLength > 0)
            {
                file.SaveAs(HttpContext.Server.MapPath("~/Img/") + file.FileName);
                //  post.ImagePath = file.FileName;
                post.PostBody = post.PostBody;
                post.Heading = post.Heading;
            }
            repository.Save(post);
        }
    }
    return RedirectToAction("display");
}

public ViewResult PublicPostDisplay()
{
    return View(repository.Posts);
}

存储库

public IEnumerable<PostModel> Posts
{
    get { return context.Posts; }
}

public void Save(PostModel Image)
{
    if (Image.PostID == 0)
    {
        context.Posts.Add(Image);
    }
    else
    {
        PostModel dbEntry = context.Posts.Find(Image.PostID);
        if (dbEntry != null)
        {
            dbEntry.ImageModel.ImagePath = Image.ImageModel.ImagePath;
        }
    }
    context.SaveChanges();
}

您需要包含错误的完整详细信息。它是有关详细信息 的内部异常,它将为您提供相关信息。但是,这可能无关紧要,因为您的模型和关系不正确。

你想要一个 PostModel 有多个 ImageModel 所以你需要一个 one-many 关系并且你的 PostModel 需要有以下 属性

public virtual ICollection<ImageModel> Images { get; set; }

并删除 int ImageIdImageModel ImageModel 属性。此外 ImageModel 应包含 public virtual PostModel Post { get; set; }

你的 POST 方法创建一个新的 PostModel 然后变成

[HttpPost]
public ActionResult Create(PostModel post, IEnumerable<HttpPostedFileBase> files)
{
    if (!ModelState.IsValid)
    {
        return View(post);
    }
    foreach (var file in files)
    {
        if (file.ContentLength > 0)
        {
            file.SaveAs(HttpContext.Server.MapPath("~/Img/") + file.FileName);
            // Initialize a new ImageModel, set its properties and add it to the PostModel
            ImageModel image = new ImageModel()
            {
                ImagePath = file.FileName
            };
            post.Images.Add(image);
        }
    }
    repository.Save(post);
    return RedirectToAction("display");
}

然而,您的代码还有多个其他问题需要解决。

  1. 首先,您的视图包含无效的嵌套表单 html 而不是 支持的。您需要删除内部 <form> 标签
  2. 你的编辑数据,所以总是使用视图模型(参考什么是 中的视图模型 MVC?) PostVM 将包含一个 属性 IEnumerable<HttpPostedFileBase> Images 并在视图中绑定到它 使用 @Html.TextBoxFor(m => m.Images, new { type = "file", multiple = "multiple" })
  3. 你根本没有验证,你的属性应该包括 验证属性,例如 [Required] 属性 HeadingBody。你需要包括 @Html.ValidationMessageFor() 视图中的每个 属性。
  4. 您的输入手册 html 不会为您提供 2 向模型绑定 并阻止任何客户端验证。始终使用 HtmlHelper 生成表单控件的方法,例如@Html.TextBoxFor(..)
  5. 不要只用文件名保存图像(多个用户可能 上传同名文件并覆盖现有文件。一 选项是使用 Guid 作为文件名,并包含一个 ImageModel 中的额外 属性 string DisplayName。参考 这个 回答 有关该方法的示例。