Following on from this question, I’m using a simple ViewModel class to test passing a strongly-typed model to a view. Whilst Darin’s answer to my original question has solved the problem I had, it’s now left me scratching my head as to why I can’t do the same thing with an EF generated class. Here’s what I have:
public ActionResult Test()
{
using (MyEntities db = new MyEntities())
{
var model = from c in db.Categories
select new CategoryViewModel { CategoryID = c.CategoryID, Name = c.Name };
return View(model.ToList());
}
}
This is CategoryViewModel:
public class CategoryViewModel
{
public int CategoryID { get; set; }
public string Name { get; set; }
}
In my view I’m simply foreaching over the model. This produces the desired results. However, one of the classes that was generated for me by EF, is Category. I was initially trying to use it to build the strongly-typed model and pass that to the view instead, like so:
public ActionResult Test()
{
using (MyEntities db = new MyEntities())
{
var model = from c in db.Categories
select new Category { CategoryID = c.CategoryID, Name = c.Name };
return View(model.ToList());
}
}
This was giving me the following error:
“The entity or complex type ‘MyProjectModel.Category’ cannot be constructed in a LINQ to Entities query.”
So my question is, what is the difference between CategoryViewModel and Category other than Category being generated for me? What is preventing me from using Category as my model type in this scenario? I’ve been looking through other questions (and answers) on SO today but I’ve been unable to find something that discusses this. I’ve also seen a few other new terms mentioned in those posts (buddy classes, automappers, POCO) but it seems premature to look into what they are without understanding the foundation of my problem.
I’d really appreciate some insight.
Though I don’t know exactly why I bet that the entity framework doesn’t like selecting
newobjects of the same type in the property you are writing your query off of. If my assumption is correct the following code should be equivalent to what you are trying to do:You would only need to select new objects when you are mapping the properties of your context’s classes to another class (IE not one that is generated by the EF).
I did a little more research into the issue, including duplicating it myself, according to the stack trace this is where the exception is thrown:
System.Data.Objects.ELinq.ExpressionConverter.CheckInitializerType(Type type)Here is the source code for
CheckInitializerType(found here):For reasons I haven’t determined yet, if the object you are trying to project properties onto has the
BuiltInTypeKindofEntityTypeorComplexType, then projection is not supported. With my testing I discovered that I can project properties onto an entity that was generated with anotheredmxfile, so the relationship with a givenObjectContextseems to boil down to theSystem.Data.Objects.DataClasses.EdmEntityTypeAttributethat decorates the generated Entity class.