Entity Framework and Read Stored Procedures - a new perspective

A few years ago at DevConnections I had a long talk with Gert Drapers (from the SQL Server team) about EF when it was still in an early beta.

I'm now at DevConnections in Las Vegas and caught up with Gert again and had an interesting follow up conversation about EF now that it is released. I really like getting the perspective of folks who bring a different expertise to the table. We talked a lot about stored procs especially the DBA perspective.

The EF designer currently [handily] supports a narrow set of stored procedures for reading and writing. The procedures need to align with entities in the data model.

Read Stored Procs often return all different shapes of data . You can map a read stored procedure to an existing entity if its resultset exactly matches the entity . Then you can call this sproc as a function of the object context, passing in any required parameters.

You can also do function mapping for read stored procs that return a scalar value or randomly shaped data. The designer supports this as well with the Function Mapping wizard, however these functions are not surfaced as methods in your objectcontext class. Instead, you need to call them with EntityClient using ExecuteScalar or ExecuteReader. (The latter was a trick I discovered when experimenting. When doing the mapping, just select maps to "None" in the wizard.)

If the entity doesn't exist, I have been creating a view in the db to represent the resultset and letting the wizard create the entity & entity set & mappings for me. Then I can do the function mapping between the sproc and the entity and call the function as necessary.

Either way however,  as a function,  these don't benefit from any of the querying capabilities of EF. You can query the results  in memory using LINQ to Object, but any additional LINQ methods you apply to the functions will get processed locally and not be part of the store command. Nor do they benefit from the deferred execution that queries give us.

Gert made, what now seems like a totally obvious point and may also be obvious to others . He said

Why not just query against the views? As long as you've got the view, why not just use that instead of the function?

Rather than being tied to the function (stored procedures) and their parameter(s), you can query against the view any way you want providing any additional filters or other operators that you like, which will be part of the store command and be executed on the server. Additionally, you can use LINQ to Entities or ObjectQueries against any of the views, rather than being forced to use EntityClient. The only downside is that you don't get the function arguments to let you know what parameters are normally expected for the procedure.

#1 Greg Shelton on 11.12.2008 at 3:36 PM

Indeed.Why not query against the views?Thanks Julie and Gert.

#2 onemenny on 11.13.2008 at 3:07 AM

this solution messes up your domain model. because i had no other option i implemented some entities that way causing "duplications" over my domain model. very confusing for other programmers integrating with the solution.you also have to be very careful when updating (partitioned views vs views that use sql functions).i really hope there will be a better mapping scenarios over the next version :(

#3 Julia Lerman on 11.19.2008 at 9:25 AM

@onemennyAre you talking about updates here? If you have an entity that maps to a table and another that maps to a view which is derived from the same table, then allow updating through the [table-based] entity AND through the [view based] entity, I can see a problem - a big one with conflicts coming from both updates.

#4 Santiago on 2.05.2009 at 1:04 PM

Dear Julie. When you perform a migration using a database that already exists, which by rule must be accessible by SP. I faced problems in mapping the entities to return results, either because they miss a column in select clause, etc.There is any walkarround to avoid this?RegardsSantiago

#5 Julia Lerman on 2.05.2009 at 1:25 PM

Hi SantiagoUnfortunately, the mapping is VERY strict and requires that the SP results map exactly to the entity. This is because EF is tryihng to automate pushing the returned data into the entity properties and can't figure out what to do if they don't line up exactly.This is not a solution that I am happy with but is it possible to modify the SP?julie

#6 Abe Park on 11.05.2009 at 12:40 PM

Hi Julie,

I got a question regarding your comment "..I have been creating a view in the db to represent the resultset".

If I have a stored procedure that returns a result set by doing a SELECT on a temp table prior to deleting the temp table.

The result set does not map to any existing Entities, so I would have to map the result set to a custom entity as you stated in your article (http://thedatafarm.com/blog/data-access/implement-select-stored-procedures-that-return-miscellaneous-data-in-ctp2-of-ef-designer/)

But, I don't like this approach because I would have to manually update the .EDMX each time I update the models from the database.

So, would I be able to somehow map the result set from a stored procedure to a view? If so, can you please point to the right reference or explain further?

From what I understand you cannot call a stored procedure from within a view.

Any suggestions or input would be greatly appreciate.

Thank you so much!

Abe

Leave a Comment