Aizen
Aizen

Reputation: 1825

MVC ViewModel EntityFrameWork ICollection,IEnumerable virtual Class

I have gone through a lot of documents and found several ways of trying to make a CreateViewModel.

I want to know what does ICollection Does.

public Payment{
   public int ID {get; set;}
   public string Details {get; set;}
   public virtual ICollection<Expense> Expenses {get; set;}


}

public Expense{
   public int ID {get; set;}
   public string MyDetails {get; set;}

}

So I guess in my View, I can Use just the plain class as virtual to make a Create Method. But if I want to use ViewModel to make a view with 2 or more DataModels for Creation. How will I go with that. Cause I guess I can always just make a

public virtual Payment payments {get; set;}
public virtual Expense expenses {get; set;}

But I am trying to ready this for Dynamically Having a Add Button Generating an Expense Details Input.

Not to mention, the IEnumerable as well, but I guess this needs an ID more suitable for Editing and Details for what I understand.

Upvotes: 1

Views: 1098

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239440

All you need is a PaymentViewModel class, where you'll use List<Expense> instead of ICollection<Expense>:

public class PaymentViewModel
{
    // ID property unnecessary here because it doesn't need
    // to be posted from the form

    public string Details { get; set; }

    // You may want to use something like `List<ExpenseViewModel>`
    // based on your needs
    public List<Expense> Expenses { get; set; }
}

With that, you add additional expense records to your form by making sure the input names are in the format of Expenses[N].MyDetails, where N is the index. Whatever JavaScript solution you use to add additional expense records to the form should create these inputs with properly indexed names. This would be a good place to use a JavaScript templating solution, or something that handles data-binding like Knockout.

For editing existing expenses, should you have the need, you just generate the fields like with any collection, but you need to use a for loop rather than the more traditional foreach:

@for (var i = 0; i < Model.Expenses.Count(); i++)
{
    @Html.EditorFor(m => m.Expenses[i].MyDetails)
}

As a side note, since you asked, ICollection<T> is the required type for entity navigation properties with Entity Framework. These reasons are very low level, but has to do with the way Entity Framework handles one-to-many and many-to-many relationships at an object level and issues such as lazy loading. However, ICollection<T> doesn't work for actually submitting items through an HTML form, due mostly to the fact that it's not indexable. That's why a view model is so important in this scenario.

Upvotes: 3

Related Questions