Entity Framework 5 – Anonymous Types
Apr9Written by:
2013/04/09 11:19 AM
Anonymous types in Entity framework is a feature that enables you to create objects without declaring a class beforehand. You create the anonymous type by using the var keyword to declare your type.
Returning Anonymous Types
Entity Framework is all about classes and entities. So a simple Linq query will return a correct type as expected.
IQueryable<Customer> cust = from c in context.Customers select c;
Works perfectly because we already have a Customer type class declared in our Model. However if we change the signature slightly we end up having to return an anonymous type. Say we want to only return a subset of columns. In SQL this is easy by just listing the column names. In Entity Framework we have to do this slightly differently. Remember we are coding against entities and classes. So the classes have all the columns as properties. The moment we deviate from that we end up with an anonymous type.
Let's use the same Linq query above but change it slightly to return only a few columns. We do this by using the new keyword in our select statement. The new keyword should give you a hint that this is indeed a new class.
IQueryable<Customer> cust = from c in context.Customers selectnew
{
c.CustomerID,
c.FirstName,
c.LastName
};
Trying to execute this throws an exception telling us that the Anonymous type cannot be converted to the Customer type.
Cannot implicitly convert type 'System.Linq.IQueryable<AnonymousType>' to 'System.Linq.IQueryable<DalEntityFrameworkDemo.Customer>'. An explicit conversion exists (are you missing a cast?)
What's happening here? Well it's simple, the Customer class does not have a signature where there are only three properties namely CustomerID, FirstName and LastName. Even though those properties are part of the Customer class. Within the customer class are various other properties.
In order to get this to work we have to use the var keyword to declare an anonymous type. So the following would work fine.
var cust = from c in context.Customers selectnew
{
c.CustomerID,
c.FirstName,
c.LastName
};
This would return a type of IQueryable<Anonymous>. In normal circumstances you can bind to this type. Problem comes in when you have to return from a method of some sort. You will soon find out that you cannot return an anonymous type. By its very nature an anonymous type is local to the procedure or method. If you tried to compile the following you will get an error thrown that says: The type or namespace name 'Anonymous' could not be found.
void Main()
{
var cust = GetCustomerColumns();
}
public IQueryable<Anonymous> GetCustomerColumns()
{
var cust = from c in context.Customers
selectnew
{
c.CustomerID,
c.FirstName,
c.LastName
};
return Cust;
}
Class Projection
One of the workarounds is to project our new anonymous type in to a new concrete type that we create. What we can do is create a new class that has only the three properties in it. Then project our Linq query to return into the new projected type.
Have a look at the following code. Here we create a new class CustomerAlt with the three needed properties. We then project the result of the Linq data into that new class.
void Main()
{
var cust = GetCustomerColumns();
}
IQueryable<CustomerAlt> GetCustomerColumns()
{
var cust = from c in Customers
selectnew CustomerAlt
{
ID = c.CustomerID,
FirstName = c.FirstName,
LastName = c.LastName
};
return cust;
}
class CustomerAlt
{
publicint ID {get;set;}
publicstring FirstName {get;set;}
publicstring LastName {get;set;}
}
This then produces a cust object of type IQueryable<CustomerAlt>. We can then return that concrete type effectively.
Related Reading:
blog comments powered by