Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you map the results of a manual SQL query to objects in Entity Framework?

In LINQ, you can write a manual SQL query, take the results from it and have LINQ "map" those into the appropriate properties of your Model classes (or at least, I'm pretty sure I read you can do that).

Is it possible to do something like that in Entity Framework?

I have an web app that's using EF, and it's CPU usage is ridiculously high compared to the traffic it has, and profiling it in my machine, all that time is (predictably) spent in the DB functions, and the largest portion of that time (> 85%) is spent by EF "generating" SQL and doing stuff before actually executing a query.

So my reasoning is that I can just go in and hardcode the SQL queries, but still use my populated Model properties in my view.

Is this possible? If so, how would I do it?

Thanks!
Daniel

like image 453
Daniel Magliola Avatar asked Oct 27 '10 19:10

Daniel Magliola


2 Answers

So what you want to do is hydrate an object from an IDataReader? It's pretty easy to write code to do this (hint: reflection! or you can get fancy and use a member initialization expression) or you can Google for myriad existing implementations on the Internet.

You can do this within EF using ObjectContext.ExecuteStoreQuery<T> or ObjectContext.Translate<T> if you already have a DbDataReader.

like image 195
jason Avatar answered Oct 13 '22 05:10

jason


1 ObjectContext.SqlQuery in EF 4.0

As said @Jason, you can :

IEnumerable<MiniClient> results = 
   myContext.SqlQuery<MiniClient>("select name,company from client");

Reference : https://msdn.microsoft.com/en-us/library/dd487208.aspx

  1. DbContext.Database.SqlQuery, in EF 4.1+

In Entity Framework 4.1+, DbContext is preferable to use to ObjectContext, so you'd better use :

DbContext myContext= new DbContext();
IEnumerable<MiniClient> results =
  myContext.SqlQuery<MiniClient>("select name,company from client");

Reference : https://msdn.microsoft.com/en-us/library/jj592907(v=vs.113).aspx

  1. dynamic and anonymous class

Too lazy to create a projection class like MiniClient ?

So you should use anonymous type and dynamic keyword :

IEnumerable<dynamic> results =
  myContext.Clients.Select( c => new {Name = c.Name, Firstname = c.Firstname});

Note : In all the samples MiniClient is not an entity of the DbContext. (=not a DbSet<T> property)

like image 30
Emmanuel DURIN Avatar answered Oct 13 '22 03:10

Emmanuel DURIN