from the answers given on my previous question topic: mvc database first issues with edmx/relationships and view showing id field, i realized that the viewmodel is the way to go, so i'll post my viewmodel related questions here.
first up, the edmx is the following
my database constraints are that 1 book may multiple authors and multiple publishers
these are my current classes:
BOOK
public partial class BOOK
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public BOOK()
{
this.AUTHORS = new HashSet<AUTHOR>();
this.PUBLISHERS = new HashSet<PUBLISHER>();
}
public int ID { get; set; }
public string TITLE { get; set; }
public int PAGES { get; set; }
public string SYNOPSIS { get; set; }
public System.DateTime PUBLISHDATE { get; set; }
public string ISBN { get; set; }
public string SUBJECT { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<AUTHOR> AUTHORS { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PUBLISHER> PUBLISHERS { get; set; }
}
PUBLISHER
public partial class PUBLISHER
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public PUBLISHER()
{
this.BOOKS = new HashSet<BOOK>();
}
public int ID { get; set; }
public string COUNTRY { get; set; }
public string NAME { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<BOOK> BOOKS { get; set; }
}
AUTHOR
public partial class AUTHOR
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public AUTHOR()
{
this.BOOKS = new HashSet<BOOK>();
}
public int ID { get; set; }
public string FIRSTNAME { get; set; }
public string LASTNAME { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<BOOK> BOOKS { get; set; }
}
right now i can successfully save book records, however they only have 1 author and 1 publisher, how can i accomplish multiple authors and publishers?
my view model:
public class BooksViewModel
{
[Key]
public int ID { get; set; }
[Display(Name = "Title")]
public string TITLE { get; set; }
[Display(Name = "Pages")]
public int PAGES { get; set; }
[Display(Name = "Synopsis")]
public string SYNOPSIS { get; set; }
[Display(Name = "Publish Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime PUBLISHDATE { get; set; }
[Display(Name = "ISBN")]
public string ISBN { get; set; }
[Display(Name = "Subject")]
public string SUBJECT { get; set; }
[Display(Name = "Publisher")]
public string NAME { get; set; }
[Display(Name = "Publisher Location")]
public string COUNTRY { get; set; }
[Display(Name = "Auhor First Name")]
public string FIRSTNAME { get; set; }
[Display(Name = "Author Last Name")]
public string LASTNAME { get; set; }
}
should i change the string properties regarding authors and publishers to lists of those objects? i.e
public class BooksViewModel2
{
[Key]
public int ID { get; set; }
[Display(Name = "Title")]
public string TITLE { get; set; }
[Display(Name = "Pages")]
public int PAGES { get; set; }
[Display(Name = "Synopsis")]
public string SYNOPSIS { get; set; }
[Display(Name = "Publish Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime PUBLISHDATE { get; set; }
[Display(Name = "ISBN")]
public string ISBN { get; set; }
[Display(Name = "Subject")]
public string SUBJECT { get; set; }
public virtual ICollection<AUTHOR> AUTHORS { get; set; }
public virtual ICollection<PUBLISHER> PUBLISHERS { get; set; }
}
and on the view just do a for cycle using this property and then simply add columns to the table within the page?
i'll post my index and create actions' of the viewmodel for your appreciation
index action:
private ApplicationDbContext db = new ApplicationDbContext();
// GET: BooksViewModels
public ActionResult Index()
{
return View(db.BooksViewModels.ToList());
}
create action:
public ActionResult Create([Bind(Include = "ID,TITLE,PAGES,SYNOPSIS,PUBLISHDATE,ISBN,SUBJECT,NAME,COUNTRY,FIRSTNAME,LASTNAME")] BooksViewModel booksViewModel)
{
if (ModelState.IsValid)
{
BOOK new_book = null;
var new_author = new List<AUTHOR>(){};
new_author.Add(new AUTHOR() { FIRSTNAME = booksViewModel.FIRSTNAME, LASTNAME = booksViewModel.LASTNAME });
var new_publisher = new List<PUBLISHER>() { };
new_publisher.Add(new PUBLISHER() { COUNTRY = booksViewModel.COUNTRY, NAME = booksViewModel.NAME });
using (ApplicationDbContext db = new ApplicationDbContext())
{
new_book = new BOOK()
{
ID = booksViewModel.ID,
TITLE = booksViewModel.TITLE,
PAGES = booksViewModel.PAGES,
SYNOPSIS = booksViewModel.SYNOPSIS,
PUBLISHDATE = booksViewModel.PUBLISHDATE,
ISBN = booksViewModel.ISBN,
SUBJECT = booksViewModel.SUBJECT,
AUTHORS = new_author,
PUBLISHERS = new_publisher
};
}
//database context
using (LibrarySQLEntities db2 = new LibrarySQLEntities())
{
db2.BOOKS.Add(new_book);
db2.SaveChanges();
}
//viewmodel context
using (ApplicationDbContext db = new ApplicationDbContext())
{
db.BooksViewModels.Add(booksViewModel);
db.SaveChanges();
}
}
return RedirectToAction("Index");
}
i have the following questions about the code above:
- is it correct to save changes made to both the viewmodel context and database context instead of just saving the data directly onto the database context and then have the viewmodel index action get the data directly from the database context?
- if the answer to question 1 is affirmative, how do i populate my viewmodel with database data?