MVC Viewmodel to display only model data

791 views Asked by At

This question is similar to this link: ViewModel to display partial information

I am hoping for an example however. I've created my model, it looks like this:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace GuestListTemplate.Models
{
    public class Guest
    {
        public int ID { get; set; }
        [Required]
        [Display(Name = "First Name:")]
        public string FirstName { get; set; }
        [Display(Name = "Last Name:")]
        public string LastName { get; set; }
        [DataType(DataType.EmailAddress)]
        [Display(Name = "e-Mail:")]
        public string eMail { get; set; }
        [DataType(DataType.PhoneNumber)]
        [Display(Name = "Phone #:")]
        public string phone { get; set; }
        public Boolean OptIn { get; set; }
        [Display(Name = "Guest Last Name:")]
        public string GuestLastName { get; set; }
        [Display(Name = "Guest First Name:")]
        public string GuestFirstName { get; set; }
        [DataType(DataType.Currency)]
        public decimal Donation { get; set; }
        public int? Attended { get; set; }

    }
}

All of this information is not neccesary for some views. I want to make a viewmodel to display only the first name, last name, donation and perhaps join the First and Last name. I am trying to do something like this but it doesn't work:

namespace GuestListTemplate.ModelViewModels
{
    public class GuestViewModel
    {
       public string FirstName { get; set; }
       public string LastName { get; set; }
       public decimal Donation {get; set;}
        [Display(Name = "Full Name")]
       public string FullName 
       {
           get { return FirstName + " " + LastName;}      
       }

    }
}

How do I tell MVC to use the GUEST model as the source of data for this viewmodel, or how do I bind them together? (The purpose for this is I thought it might help performance of my application, Will it actually help performance??). I understand how to use Viewmodels to display data from multiple tables and pull in ALL data but in this case I want to pull only certain data from one table. Last, Is this better accomplished in the controller?

I hope this question makes sense. Would it be better to use a LINQ query such as

var Guests = db.Guest.Include(g => g.firstname, g.lastname, g.donation);
return (Guests.ToList());

(I understand the above command might not be exact syntax bbut you get the idea). If this is a better way to do it can someone demonstrate a basic way of doing this with the entire viewmodel code. I am pretty good with LINQ, so if someone offers a basic example I should be able to make it work for my purposes.

EDIT:

This worked for me (as well the interfaces outlined in the answer below):

ViewModel is the same as above.

Here is what I do in the controller:

var viewmodel = db.Guests.Select(g => new GuestListIndexData
            {
                ID = g.ID,
                FirstName = g.FirstName,
                LastName = g.LastName,
                Donation = g.Donation,
                Attended = g.Attended
            }).OrderBy(g => g.FirstName);

            return View(viewmodel.ToList());

My view is essentially the same as what I listed above as well. This works, but i'm not sure how much faster performance I am actually getting out of it so I probably won't use it until I am working with very large databases.

1

There are 1 answers

3
Brian Mains On BEST ANSWER

I was able to achieve this with interfaces, such as this:

public interface INameEntity
{
   string FirstName { get; set; }

   string LastName { get; set; }
}

And add this to Guest:

public class Guest : INameEntity

And use INameEntity in the partial:

@model INameEntity

@Html.TextBoxFor(i => i.FirstName)

This is the technique I use and it works great if Guest is your direct model in the parent view. If there is a parent model class, it's doable but a little more complex setup.