I noticed in the Entity Framework designer that you can map stored procedures for Insert, Update, and Delete operations. Is there any way to do this for Select operations as well, or is there a new direction for database access code where we don't really write stored procedures for our basic select operations any more?
The company I work for is pretty adamant about always using stored procedures for every database operation, even though the Entity Framework makes the calls safe by calling sp_executesql.
It seems like both LINQ to SQL and Entity Framework have moved away from using stored procedures for selecting the data. Is this an accurate statement?
Just to clarify my question:
I have a table in my database called Product. I use the wizard in the Entity Framework to generate my models...so I now have an Entity called Product. When I do the following query:
db.Products.SingleOrDefault(p => p.Id == 1);
It generates code similar to:
EXEC sp_executesql N'SELECT * FROM Product'
When I really want to do something like:
EXEC up_GetProduct @Id = 1
If it's not possible to do that using SingleOrDefault I'm fine with that. I'd much rather have the following:
db.Products.GetProduct(1);
Is this something that is normally done or do most people just have it dynamically generate the SQL?
The entities themselves don't allow stored procedures for selecting. There are several reasons. Off the top of my head:
Order
andOrderItem
tables, how do you join? You either runSelectOrder
and for each order you runSelectOrderItem
(1+n queries), or have one stored procedure that returns both, either as one result set with duplicatedOrder
data, or two result sets. Then you have to specify how that maps to the entities. If you have to manually specify the mapping, it defeats the purpose of the entity relationships you had to set up.IQueryable
to the business layer or UI layer (up to you). You then do your LINQ filtering which modifies the SQL and makes it efficient. With stored procedures, you would once again have to somehow manually define all this, or do the filtering with LINQ to objects.select new { o.Column1, o.Column2 }
. That generates SQL which only selects those 2 columns you need. Very useful if you have aBLOB
/VARCHAR(MAX)
. With stored procedures you usually return every column (wasteful in many ways). You CAN split intoGetOrderDetailMain
andGetOrderDetailImages
(or similar) stored procedures, but it's not feasible to create each combination.In my opinion, if you'll be using the EF framework, let it do CRUD for you. Use stored procedures for complex logic like full text searching, a specific query which is too slow, etc. Otherwise you won't get much benefit from it.
Edit: Of course there are benefits to stored procedures. They are preparsed/precompiled, well defined "database API", you don't need to give access to tables (though with SP CRUD, you can in effect do the same things), easier to debug/tune the queries, easier to know which queries to tune, can do batch processing, etc. For simple CRUD, though, you have to ask yourself if the time-to-implement/manage overhead of stored procedures is worth it.
You can certainly use stored procedures for selects in Entity Framework. I have had great success with function imports, complex types, and stored procedures with EF4. And, they're not too difficult to set up, either.
I will warn you of one thing: if you are using SQL Server 2005, you may have to recompile any stored procedure you want to use with
SET FMTONLY OFF
if you want to allow the entity modeler to generate a complex type for you. See this question for more detail on that.See the Quickstart for more information.