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