Reputation: 31
I have taken primary key (Userid) as foreign key in 'Book' table.It is one to many relationship i.e a single user is able to upload multiple books. BookID is auto incremented.Whenever user clicks 'Upload Books' button, I need to store the name of the book and its path in database with userid as foreign key from User
table and BookID
to be auto increment.
I am having the following exception at db.SaveChanges()
:
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.
Inner exception is:
Cannot insert the value NULL into column 'Id', table 'BooksModule.dbo.Book'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated.
Below is my code:
Here is my model class: 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; }
}
Here is my model class of Users: 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; }
}
here is a method:
[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();
}
}
Here is a 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>
Upvotes: 0
Views: 3841
Reputation: 118937
Entity Framework will pick Id
as the primary key, and as yours is a string
you need to supply it yourself (which you are not doing.)
It's preferable to have an int
as your primary key so EF can make it an identity
column in the database.
A few other observations too:
FileUpload
post action is taking a Book
object that isn't used other than as a variable in your action, instead just declare a new Book
object inside the method.fileName
and path
variables are not needed.Id
and BookId
? I would remove BookId
.I would suggest your Book.cs
looks like this:
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; }
}
And your post action:
[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();
}
}
Update
From the comments you made above, there is an additional change you need to make to the Book
class. First you need to tell Entity Framework that your Id
property if the key using the [Key]
attribute. Secondly for the Id
column you should do one of these:
Id
(as Entity Framework will create one for you)Id
to UserId
to allow Entity Framework to automatically link it to the User
property.User
property to tell it the name of the column to use, for example [ForeignKey("Id")]
I would suggest either 1 or 2 so it is more obvious what the column is when looking at the database:
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; }
}
Upvotes: 1