Tweaking class generation in Entity Framework to use Stored Procedures - c#

I am looking for some guidance on how to tweak the T4 code generation of the entity classes in EntityModel.tt and possibly EntityModel.Context.tt (I'm using POCO classes) to force any queries on entities to use stored procedures (I already have the EntitySQL.tt generating all my Stored procedures)
For example, something like
context.MyEntities().Single(c => c.id == 5)
Would not generate SQL, but would call the SP `sp_GetMyEntities'
If you have a better strategy for achieving the same result I would be glad to learn about it.
UPDATE
At this point I'm interested only in the READ part of CRUD. And there are no joins. Just simple loading of a single entity by ID. Theoretically the SP can be set to accept the ID of the loaded item as a parameter, to avoid loading the whole table (in this case there will be bn need for the .Single(c => c.id == 5) part and ID will be provided to the MyEntities object.
This is for a "database first" implementation

Code first does not support mapping to stored procedures. Model first and Database first flows do support mapping to stored procedures but it does not work the way you would like to use it since stored procedures are not compoosable (i.e. if you do .Single() the filtering will happen at best on the client not in the database - for performance reasons you want the filtering to happen on the database site since you probably don't want to bring the whole database to the client just to select one entity). Core libraries of Entity Framework 5 that ship with .NET Framework 4.5 support TVFs which are composable and should make it possible what you are after but again not in code first scenarios.

Related

Is it possible to use Entity Framework and keep object relations in the code and out of the database

I'm having a hard time just defining my situation so please be patient. Either I have a situation that no one blogs about, or I've created a problem in my mind by lack of understanding the concepts.
I have a database which is something of a mess and the DB owner wants to keep it that way. By mess I mean it is not normalized and no relationships defined although they do exist...
I want to use EF, and I want to optimize my code by reducing database calls.
As a simplified example I have two tables with no relationships set like so:
Table: Human
HumanId, HumanName, FavoriteFoodId, LeastFavoriteFoodId, LastFoodEatenId
Table: Food
FoodId, FoodName, FoodProperty1, FoodProperty2
I want to write a single EF database call that will return a human and a full object for each related food item.
First, is it possible to do this?
Second, how?
Boring background information: A super sql developer has written a query that returns 21 tables in 20 milliseconds which contain a total of 1401 columns. This is being turned into an xml document for our front end developer to bind to. I want to change our technique to use objects and thus reduce the amount of hand coding and mapping from fields to xml (not to mention the handling of nulls vs empty strings etc) and create a type safe compile time environment. Unfortunately we are not allowed to change the database or add relationships...
If I understand you correct, it's better for you to use Entity Framework Code First Approach:
You can define your objects (entities) Human and Food
Make relations between them in code even if they don't have foreign keys in DB
Query them usinq linq-to-sql
And yes, you can select all related information in one call.
You can define the relationships in the code with Entity Framework using Fluent API. In your case you might be able to define your entities manually, or use a tool to reverse engineer your EF model from an existing database. There is some support for this built in to Visual Studio, and there are VS extensions like EF Power Tools that offer this capability.
As for making a single call to the database with EF, you would probably need to create a stored procedure or a view that returns all of the information you need. Using the standard setup with lazy-loading enabled, EF will make calls to the database and populate the data as needed.

Is it a good approach to query the database only through stored procedures?

When I am developing an ASP.NET website I do really like to use Entity Framework with both database-first or code-first models (+ asp.net mvc controllers scaffolding).
For an application requiring to access an existing database, I naturally thought to create a database model and to use asp.net mvc scaffolding to get all the basic CRUD operations done in a few minutes with nearly no development costs.
But I discussed with a friend who told me that accessing data stored in the database only through stored procedures is the best approach to take.
My question is thus, what do you think of this sentence? Is it better to create stored procedures for any required operations on a table in the database (e.g. create and read on this table, update and delete only on another one, ...)? And what are the advantages/disadvantages of doing so instead of using a database-first model created from the tables in the database?
What I thought at first is that it double costs of development to do everything through stored procedures as you have to write these stored procedures where Entity Framework could have provided DbContext in a few clicks, allowing me to use LINQ over Entities, ... But then I've read a few stuff about Ownership Chains that might improve security by setting only permissions to execute stored procedures and no permissions for any operations (select, insert, update, delete) on the tables.
Thank you for your answers.
Its a cost benefit analysis. Being a DB focused guy, I would agree with that statement. It is best. It also makes you code easier to read (no crazy sql statements uglifying it). Increased performance with cached execution plans. Ease of modifying the querying without recompiling the code, eetc.
Many of the ppl I work with are not all that familiar with writing SPROCs so it tends to be a constant fight with them use them. Personally I dont see any reason to ever bury SQLStatments in your code. They tend to shy away from them b/c it is more work for them up front.
Yes, it's a good approach.
Whether it's the best approach or not, that depends on a lot of factors, some of them which you don't even know yet.
One important factor is how much furter development there will be, and how much maintainence. If the initial development is a big part of the total job, then you should rather use a method that gets you there as fast and easy as possible.
If you will be working with and maintaining the system for a long time, you should focus less on the initial development time, and more on how easy it is to make changes to the system once it's up and running. Using stored procedures is one way to make the code less depending on the exact data layout, and allows you to make changes without a lot of down time.
Note that it's not neccesarily a choise between stored procedures and Entity Framework. You can also use stored procedures with Entity Framework.
This is primarily an opinion based question and the answer may depend on the situation. Using stored procedure is definetely one of the best ways to query the database but since the emergence of Entity Framework it is widely used. The advantage of Entity Framework is that it provides a higher level of abstraction.
Entity Framework applications provide the following benefits:
Applications can work in terms of a more application-centric conceptual model, including types with inheritance, complex members,
and relationships.
Applications are freed from hard-coded dependencies on a particular data engine or storage schema.
Mappings between the conceptual model and the storage-specific schema can change without changing the application code.
Developers can work with a consistent application object model that can be mapped to various storage schemas, possibly implemented in
different database management systems.
Multiple conceptual models can be mapped to a single storage schema.
Language-integrated query (LINQ) support provides compile-time syntax validation for queries against a conceptual model.
You may also check this related question Best practice to query data from MS SQL Server in C Sharp?
following are some Stored Procedure advantages
Encapsulate multiple statements as single transactions using stored procedured
Implement business logic using temp tables
Better error handling by having tables for capturing/logging errors
Parameter validations / domain validations can be done at database level
Control query plan by forcing to choose index
Use sp_getapplock to enforce single execution of procedure at any time
in addition entity framework will adds an overhead for each request you make, as entity framework will use reflection for each query. So, by implementing stored procedure you will gain in time as it's compiled and not interpreted each time like a normal entity framework query.
The link bellow give some reasons why you should use entity framework
http://kamelbrahim.blogspot.com/2013/10/why-you-should-use-entity-framework.html
Hope this can enlighten you a bit
So I'm gonna give you a suggestion, and it will be something I've done, but not many would say "I do that".
So, yes, I used stored procedures when using ADO.NET.
I also (at times) use ORM's, like NHibernate and EntityFramework.
When I use ADO.NET, I use stored procedures.
When you get data from the database, you have to turn it into something on the DotNet side.
The quickest thing is to put data into a DataTable or DataSet.
I no longer favor this method. While it may make for RAPID development ("just stuff the data into a datatable")......it does not work well for MAINTENANCE, even if that maintenance is only 2-3 months down the road.
So what do I put the data into?
I create DTO/POCO objects and hydrate the data from the database into these objects.
For example.
The NorthWind database has
Customer(s)
Order(s)
and OrderDetail(s)
So I create a csharp class called Order.cs, Order.cs and OrderDetail.cs.
These ONLY contain properties of the entity. Most of the time, the properties simple reflect the columns in the database for that entity. (Order.cs has properties, that simulate a Select * from dbo.Order where OrderID = 123 for example).
Then I create a child-collection object
public class OrderCollection : List<Order>{}
and then the parent object gets a property.
public class Customer ()
{
/* a bunch of scalar properties */
public OrderCollection Orders {get;set;}
}
So now you have a stored procedure. And it gets data.
When that data comes back, one way to get it is with an IDataReader. (.ExecuteReader).
When this IDataReader comes back, I loop over it, and populate the Customer(.cs), the Orders, and the OrderDetails.
This is basic, poor man's ORM (object relation mapping).
Back to how I code my stored procedures, I would write a procedure that returns 3 resultsets, (one db hit) and return the info about the Customer, the Order(s) (if any) and the OrderDetails(s) (if any exist).
Note that I do NOT do alot of JOINING.
When you do a "Select * from dbo.Customer c join dbo.Orders o on c.CustomerID = o.CustomerId, you'll note you get redundant data in the first columns. This is what I do not like.
I prefer multiple resultsets OVER joining and bringing back a single resultset with redundant data.
Now for the little special trick.
Whenever I select from a table, I always select all columns on that table.
So whenever I write a stored procedure that needs customer data, I do a
Select A,B,C,D,E,F,G from dbo.Customer where (......)
Now, alot of people will argue that. "Why do you bring back more info than you need?"
Well, real ORM's do this anyway. So I am poor-man reflecting this.
And, my code for taking the resultset(s) from the stored procedure to turn that into instances of objects........stays consistent.
Because if you write 3 stored procedures, and each one selects data from Customer table, BUT you select different columns and/or in a different order, youre "object mapper" code needs to have a method for each stored procedure.
This method of ADO.NET has served me well.
And, once my team swapped out ADO.NET for a real ORM, and that transition was very pain free because of the way we did the ADO.NET from the get go.
Quick rules of thumb:
1. If using ADO.NET, use stored procedures.
2. Get multiple result-sets, instead of redundant data via joins.
3. Make your columns consistent from any table you select from.
4. Take the results of your stored procedure call, and write a "hydrater" to take that info and put into your domain-model as soon as you can. (the .cs classes)
That has served me well for many years.
Good luck.
In my opinion :
Stored Procedures are written in big iron database "languages" like PL/SQL or T-SQL
Stored Procedures typically cannot be debugged in the same IDE your write your UI.
Stored Procedures don't provide much feedback when things go wrong.
Stored Procedures can't pass objects.
Stored Procedures hide business logic.
Source :
http://www.codinghorror.com/blog/2004/10/who-needs-stored-procedures-anyways.html

From TypeDataset to Entity framework

I am working on window application developed using SCSF and we are using sybase database. As practise we create typedataset in the .net project and then populate them using framework method and for all the sql statement we write stored procedure in the database.
So we have type dataset in memory so I am using linq to select records from datatable. Can I step one step further and use something related to Entity Framework?
Can it reduce my work? I don't have hands-on experience with Entity Framework but can you suggest something in this scenario?
Thanks,
Denish
Entity framework uses similar concepts as the type datasets except for:
The ability to have a class structure that is not exactly the same as the table structure (e.g. class hierarchy, splitting tables into multiple classes, joining tables into one class).
The ability to use LINQ to perform queries in the database instead of in memory.
Entity framework also lets you map results of stored procedures to classes and bring results into memory if you need to run a query that is faster in memory or not translatable to SQL.
For most SQL queries the LINQ to Entity will be effective enough, so you will probably end up writing less stored procedures.
You will have to learn how to use EF and LINQ effectively and use can use 3rd party tools such as Entity Framework Profiler to help you.

Linq-to-SQL vs Entity Framework in database-first approach

I got confused on what are the differences between Linq-to-SQL and Entity Framework when following the database first approach as I can not find any clear differences.
In my case when I was using Linq-to-SQL I used to create the tables then I use Linq-to-SQL to create the classes that represents the tables, and now when I switch to Entity Framework I am still following the same steps (creating the database tables then create the associated classes using EF).
And I am interacting with these classes on the same way, for example I used to query the User class using the same syntax and approach but one time when the User class was created using Linq-to-SQL and the other time when it was created using EF, so where is the difference ?
public IQueryable<User> findstudents(string term)
{
return from student in entities1.Users
where student.UserID.Contains(term)
select student;
}
Second question if I use EF to map the tables into classes, is it still possible to use Linq-to-SQL in the same application to query the EF classes?
LINQ is a base technology - that's the syntax that gives you the SQLish query options in C# - that's totally independent of whether you use Linq-to-SQL or EF. So if you want to query your data classes using the LINQ syntax - you can do that with both frameworks - but once you use Linq-to-SQL and once you use Linq-to-Entities. You cannot use Linq-to-SQL against an Entity Framework EDMX model.
Linq-to-SQL is great
if you need very simple 1:1 mapping - one table equals one class in your domain model
if you never need anything else but SQL Server (Linq-to-SQL doesn't support anything else)
if you want to be up and running really quickly
Entity Framework on the other hand
supports multiple backends (SQL Server, Oracle, Firebird - other will likely follow)
supports a full conceptual data modelling strategy - you define the physical model in the database, the conceptual model in your app, and the mapping between the two
gives you the ability to handle things like mapping a single business entity to several tables
support table-per-hierarchy and table-per-class inheritance scenarios
support refreshing/updating your model (EDMX file) from the database when things change (in Linq-to-SQL, you basically have to drop + recreate those entities involved - thus loosing all your customizations you might have made)
In brief: Linq-to-SQL is a great, simple and lean'n'mean ORM for SQL Server - use it, if it does all you need. Entity Framework is quite a different beast, much more capable, but also more complex, much bigger - perfect for your next enterprise-critical app, but probably overkill for your personal blog app :-)
If you want to create something that's "future-proof" and will use the OR technology that Microsoft is pushing into the future, then you should go with Entity Framework. Especially in v4, it's also a lot easier to use, a lot more slimmed down and more useful than ever before.

Mapping select stored procedures in entity framework

My scenario
I'm using Visual Studio 2010 with Entity Framework 4.1
I have a legacy database with many tables and many stored procedures.
I'm writing an ASP.NET C# program using MVC 3
I have adopted the 'database first' design using ADO.NET DbContext so I have an edmx with all the models and associations and navigation properties nicely set up.
I can map the insert, update, delete procedures to the relevant models.
I've used 'Function Import' to import other stored procedures.
However, I can't find a way to map my Select procedures to select actions (select by id, select list, select by filter etc).
EF seems to use lazy loading so what I want to happen is when an object fetches its child objects it uses the stored procedures already written.
(The select procedures take into account an 'IsDeleted' flag, and use the 'ORDER BY' clause, amongst others)
I see from this article
http://weblogs.asp.net/scottgu/archive/2007/08/16/linq-to-sql-part-6-retrieving-data-using-stored-procedures.aspx
that Linq to SQL allows drag and drop of SPs, which sounds, more or less, exactly what I want.
I've also come across the term DefiningQuery.
http://msdn.microsoft.com/en-us/library/cc982038.aspx
Is this what I want? I don't like the note 'Any changes made to the storage model, including defining queries, will be overwritten when you run the Update Model Wizard.'
In summary, what I want to happen is when an object fetches its child objects it uses my stored procedures.
Can I achieve my goal using Entity Framework?
Have I missed something obvious?
Or should I try to be really clever and modify the db Entity T4 template, so that, for example, my generated Address model has this property:
public virtual ICollection<AddressLine> AddressLines {
get{
DBWrapper _db = new DBWrapper();
return _db.GetAddressLines(AddressID);
}
set{};
}
where GetAddressLines is custom function that calls a function import and does the neccessary conversions.
It is not possible. You can import your stored procedures as function imports and manually execute them but you cannot replace queries generated by EF with custom stored procedures.
Except that you can, sort of.
Take your most basic select stored procedure (i.e., the one which is closest to "select * from mytable", and use it to define a view in your database. Have entity framework use this "myview" instead of "mytable". Then map your insert, update and delete stored procs for this view-based entity as you did originally for your table.
Finally, use function imports for your more selective selects, and define them to return collections of your entity. So if you had something like a Person entity, and you had a stored proc called something like FetchPersonByAge(int), your entity would end up with a static method called something like "GetByAge(int)". You could then call it in code like this: var people33 = Person.getByAge(33);
I have done this, and it worked quite well, allowing me to respect a legacy database's designers demand that all database access be through their stored procs, and no user code directly accessing tables. See Julie Lerman's article:
http://msdn.microsoft.com/en-us/data/gg699321.aspx
Dave

Categories

Resources