我已将主键(Userid)作为“Book”表中的外键。它是一对多关系,即单个用户可以上传多本书。 BookID自动递增。当用户点击“上传图书”按钮时,我需要将图书的名称及其路径存储在数据库中,其中userid作为外键来自User
表和BookID
以自动增加
我在db.SaveChanges()
处遇到以下异常:
EntityFramework.dll中发生了'System.Data.Entity.Infrastructure.DbUpdateException'类型的异常但未在用户代码中处理附加信息:更新条目时发生错误。有关详细信息,请参阅内部异常。
内部例外是:
无法将值NULL插入列'Id',表'BooksModule.dbo.Book';列不允许空值。 INSERT失败。\ r \ n语句已终止。
以下是我的代码:
这是我的模型类:Book.cs
public partial class Book
{
public string Id { get; set; }
public int BookID { get; set; }
public string BookName { get; set; }
public string BookPath { get; set; }
public virtual User User { get; set; }
}
这是我的用户模型类:User.cs
public partial class User
{
public User()
{
this.Books = new HashSet<Book>();
}
public string Id { get; set; }
public string UserName { get; set; }
public virtual ICollection<Book> Books { get; set; }
}
这是一个方法:
[HttpGet]
public ActionResult FileUpload(string id)
{
return View();
}
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase file,Book bk)
{
var filepath = "";
var fname = "";
if (ModelState.IsValid)
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/Uploads"), fileName);
filepath = path;
fname = fileName;
file.SaveAs(path);
}
bk.BookName = fname;
bk.BookPath = filepath;
db.Books.Add(bk);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
else
{
return View();
}
}
以下是一个观点:
<div class="sidebar">
@using (Html.BeginForm("FileUpload", "UploadBooks", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.ValidationSummary();
<fieldset>
<legend>Upload a file</legend>
<div class="editor-field">
@Html.TextBox("file", "", new { type = "file" })
</div>
<input type="submit" id="btnSubmit" class="btn btn-default2" value="Upload" />
</fieldset>
}
</div>
答案 0 :(得分:1)
实体框架将选择Id
作为主键,而您自己需要string
来提供它(您不会这样做。)
最好使用int
作为主键,以便EF可以使其成为数据库中的identity
列。
其他一些观察结果:
FileUpload
帖子操作正在使用一个Book
对象,该对象除了作为操作中的变量之外没有被使用,而只是在方法中声明一个新的Book
对象。 / LI>
fileName
和path
个变量。Id
和BookId
?我会删除BookId
。我建议您Book.cs
看起来像这样:
public partial class Book
{
public int Id { get; set; }
public string BookName { get; set; }
public string BookPath { get; set; }
public virtual User User { get; set; }
}
你的帖子:
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
if (file.ContentLength > 0)
{
fname = Path.GetFileName(file.FileName);
filepath = Path.Combine(Server.MapPath("~/App_Data/Uploads"), fileName);
file.SaveAs(fname);
Book bk = new Book
{
BookName = fname,
BookPath = filepath
};
db.Books.Add(bk);
db.SaveChanges();
}
return RedirectToAction("Index", "Home");
}
else
{
return View();
}
}
<强>更新强>
根据您上面的评论,您需要对Book
课程进行其他更改。首先,如果密钥使用Id
属性,您需要告诉实体框架您的[Key]
属性。其次,对于Id
列,您应该执行以下操作之一:
Id
(因为实体框架会为您创建一个)Id
重命名为UserId
,以允许Entity Framework自动将其链接到User
属性。User
属性添加属性,告诉它要使用的列的名称,例如[ForeignKey("Id")]
我建议使用1或2,这样在查看数据库时列更明显:
public partial class Book
{
[Key]
public int BookId { get; set; }
public string BookName { get; set; }
public string BookPath { get; set; }
public string UserId { get; set; }
public virtual User User { get; set; }
}