Flattening nested object properties in Entity Framework & ASP.NET MVC

When using the Microsoft ASP.NET MVC framework, I always create a set of partial classes relating to my database objects to centralise validation and add additional properties. When using Telerik Grid control for MVC, however, you cannot bind, page or sort when there is a column which is bound to such a property because Entity Framework fails to translate those properties to SQL.

Occasionally, you just need to create a flattened representation of a set of objects and one solution is to use LINQ "projection" to output a flat view model object:

Here’s the ActionResult which, using projection, flattens the UserModel enumerables into a flat UserViewModel:

 [GridAction]        public ActionResult _UserGrid()        {            var model = from o in new UserRepository().GetUsers()                        select new UserViewModel                        {                            Full_Name = o.Person.Person_nameFirst,                            Created = o.Created,                            Email = o.Person.First,                            ID = o.ID,                            Username = o.Username                        };            return View(new GridModel { Data = model });        }

Here’s the view model itself:

namespace Project.EF{    public class UserListViewModel    {        public int ID        {            get;            set;        }        public string Full_Name        {            get;            set;        }        public string Username        {            get;            set;        }        public string Email        {            get;            set;        }        public DateTime? Created        {            get;            set;        }    }}

And here’s our original partial class

namespace Project.EF{    [Bind(Include = "myfields")]    [MetadataType(typeof(User_Validation))]    public partial class User    {        public string FullName        {            get { return string.Format("{0} {1}", Person.First, Person.Last); }        }        public bool IsValid        {            get { return (GetRuleViolations().Count() == 0); }        }        public bool IsValidRecord        {            get { return (ID > 0); }        }        public IEnumerable GetRuleViolations()        {            yield break;        }    }    public class User_Validation    {        [HiddenInput(DisplayValue = false)]        public int ID { get; set; }    }}

Leave a Reply