0

i'm new in asp.net MVC and I/m use view model to poppulate the dropdown list and group of checkboxes. I use SQL Server 2012, where have many to many relationships between Students - Books; Student - Cities. I need collect StudentName, one city and many books for one student.

I have next questions:
1. How can I get the values from database to my StudentBookCityViewModel?
2. How can I save the values to my database in [HttpPost] Create method?

Here is the code:

MODEL

public class Student {
    public int StudentId { get; set; }
    public string StudentName { get; set; }

    public ICollection<Book> Books { get; set; }
    public ICollection<City> Cities { get; set; }
}

public class Book {
    public int BookId { get; set; }
    public string BookName { get; set; }
    public bool IsSelected { get; set; }

    public ICollection<Student> Students { get; set; }
}

public class City {
    public int CityId { get; set; }
    public string CityName { get; set; }
    public bool IsSelected { get; set; }

    public ICollection<Student> Students { get; set; }
}

VIEW MODEL

public class StudentBookCityViewModel {
    public string StudentName { get; set; }
    public IList<Book> Books { get; set; }

    public StudentBookCityViewModel()
    {
        Books = new[]
                    {
                        new Book {BookName = "Title1", IsSelected = false},
                        new Book {BookName = "Title2", IsSelected = false},
                        new Book {BookName = "Title3", IsSelected = false}
                    }.ToList();
    }

    public string City { get; set; }
    public IEnumerable<SelectListItem> CityValues
    {
        get
        {
            return new[]
                       {
                           new SelectListItem {Value = "Value1", Text = "Text1"},
                           new SelectListItem {Value = "Value2", Text = "Text2"},
                           new SelectListItem {Value = "Value3", Text = "Text3"}
                       };
        }
    }
}

Context

public class EFDbContext : DbContext{
    public EFDbContext(string connectionString) {
        Database.Connection.ConnectionString = connectionString;
    }

    public DbSet<Book> Books { get; set; }
    public DbSet<Student> Students { get; set; }
    public DbSet<City> Cities { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<Book>()
            .HasMany(x => x.Students).WithMany(x => x.Books)
            .Map(x => x.MapLeftKey("BookId").MapRightKey("StudentId").ToTable("StudentBooks"));

        modelBuilder.Entity<City>()
            .HasMany(x => x.Students).WithMany(x => x.Cities)
            .Map(x => x.MapLeftKey("CityId").MapRightKey("StudentId").ToTable("StudentCities"));
    }
}

Controller

public ActionResult Create()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Create()
    {
        //I don't understand how I can save values to db

        context.SaveChanges();

        return RedirectToAction("Index");
    }

View

@model UsingEFNew.ViewModels.StudentBookCityViewModel

@using (Html.BeginForm())
{
    <div id="ContactContainer">
        <div>Your Name:</div>
        <div>
            @Html.TextBoxFor(model => model.StudentName)
        </div>

        <div>Genre:</div>
        <div> 
            @Html.DropDownListFor(model => model.City, Model.CityValues)
        </div>
        <div>Books:</div>
        <div>
            @for (int i = 0; i < Model.Books.Count; i++)
            {
                <div>
                    @Html.HiddenFor(x => x.Books[i].BookId)
                    @Html.CheckBoxFor(x => x.Books[i].IsSelected)
                    @Html.LabelFor(x => x.Books[i].IsSelected, Model.Books[i].BookName)
                </div>
            }
        </div>
        <div>
            <input id="btnSubmit" type="submit" value="Submit" />
        </div>
    </div>
}
1
  • This belongs at stackoverflow... Commented Jul 1, 2013 at 14:54

1 Answer 1

2

You can get values from db directly in the controller

    public ActionResult Create()
        {
                var vm = new StudentBookCityViewModel();
                using(var ctx = EFDbContext(connectionString))
                {
                var student = ctx.Students.First();
                vm.StudentName=student.Name;
    vm.Books = student.Books.ToList(); //make sure to call ToList() to load values from db
    ...
                }
                return View(vm);
            }
        [HttpPost]
    public ActionResult Create(StudentBookCityViewModel model)
    {

        //I don't understand how I can save values to db

        //here you have the model with all infomation from the form
       foreach(var book in model.Books){
        context.Books.First(b=>b.BookId == book.BookId).IsSelected = book.IsSelected;
}
        context.SaveChanges();

        return RedirectToAction("Index");
    }
Sign up to request clarification or add additional context in comments.

3 Comments

This is a good solution, but doing so in your ViewModel is a bit more 'proper.'
I prefer to have the service layer which loads and saves the data into the database. But the user said he is new to MVC, so the easiest way is the best, as for me
There's no problem with inmediatly implementing service behaviour. Using ur context inside ur controller is, imo, a bad practise. It works, but it's not the way to go considering SOLID principles, Testability, Maintainability. As long as you mention this solution is not supposed to be seen as "the best" I pretty much agree this is a good path to start on. Nevertheless, be aware that there are better ways! When learning MVC, focus should not be on architecture.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.