by Johnny Nouel
24. abril 2011 15:22
ORM's are great. They remove that dirty job of writing all that code to handle the information getting in and out of the database engine and let you focus on what's really important. Application Logic! In this post I'm going to focus on using Stored Procedures in Entity Framework. Let's suppose you already have a class developed that maps to the Northwind Database and you want to use a stored procedure to update some tables after transactional data has been updated, for example. Or perhaps you just want to execute the "Total Sales By Category" stored procedure to get that information. The Northwind Model that the Entity Designer generated included all tables, views and stored procedures if indicated in the wizard at the moment of creation. Tables and Views are mapped and ready to be used in our code but the Stored Procedures require one more step. Please look at the code snippet below where you see one of the views being used to get the details of and order: public List<Order_Details_Extended> GetView_OrderDetailsExtended(int orderid)
{
return db.Order_Details_Extendeds.Where(m => m.OrderID==orderid).ToList();
}
If we wanted to execute the stored procedure SalesByCategory we need to import it as a function into our model. Once we do that it will appear below the highlighted element in our model tree.
We can do so by Right Clicking in the Function Imports element.
. or Right Clicking the Stored Procedure in the list of Stored Procedures in our model.
.and selecting Add Function Import from the cascade menu. If you use the former method you need to tell the Add Function Dialog Box that appears the name of the function and the stored procedure to use; with the latter method this is information is obtained from your selection.
You can now select what you want back as a return value once the Stored Procedure is done executing.
None. Even though it says None you will actually get back an integer (int) value indicating how many records were processed.
Scalars. If your stored procedure returns a single value you can indicate here what type is the value returned.
Complex. EF Designer will create a new complex type based on the schema. More on this below.
Entities. Select the entity that corresponds to the schema returned by the stored procedure.
If you Click the Get Column Information button the schema of the columns returned will be available and the Create New Complex Type buttons becomes available. The EF Designer will create then a new type to use based on the schema of the columns returned. You can name this new type in the DropDownBox as shown in the picture below.
The Complex Types you create will be available in the model tree as shown below:
Now we can use the stored procedure in our code. For example, let's create a method that returns Sales By Category in a List of our new Complex Type, SalesByCategory_Result.
public List<SalesByCategory_Result> GetSalesByCategory(string category, string year)
{
return db.SalesByCategory(category, year).ToList();
}
Stored Procedures in Entity Framework are not limited to what this blog post has just touched. You can actually have your model work in the CRUD operations against Stored Procedures defined for this purpose in the database. But this will be discussed in another post.
Right click on an Entity that represents a Table in the EF Designer Diagram and select Stored Procedure Mapping.
Here you can select the Stored Procedure to execute when any of the Update, Delete or Select operations are to be called.
When you select a Stored Procedure you can then configure the column/field mapping for the Parameters and the Result Column Bindings for the values to be returned. Please look at the screenshot below that shows you the elements involved in this mapping.
And that's it. Hope it helps!
by Johnny Nouel
22. marzo 2011 20:02
I had a difficult time trying to decide the title of this post. I couldn't decide between the current title and "Entities from outer space invade .NET and steal its methods". Of course I know you agree with my current selection.
The thing is that I'm actually kind of new to the EF ORM. And as I go along using it in my new project issues and discoveries come to my attention. Some of them are plain silly and others hidden even from Google and Bing (or so I thought).
I developed a Class Library which contains the EF Model for one of the databases I'm working on. I then add this library as a reference in another project in order to consume it. The thing is that the Entities Object was not exposing some of the properties or methods that were available in the Class Library.
Let's suppose I just built a Library that works against the Pubs Database. I added a reference to this project in a Windows Forms project.
I have a method called GetData that instantiates the pubsEntities object and when Intellisense does its magic some methods like SaveChanges are missing. Also, the properties and methods of tables are gone as well. Take a look:
The SaveChanges method is nowhere to be seen. At first I tried to figure it out without trying to compile the application but the problem was staring at my face and did not want to see it. After compiling and hovering the mouse over the underlined issues in the code you could easily read that an assembly was missing.
Yes. That's right! All you have to do is add the System.Data.Entity assembly to the project consuming the EF Class Library and voila! All methods are back!
The code now looks ok (it does now that I changed the method name from GetData to AddSomeAuthor):
private void AddSomeAuthor()
{
Pubs.pubsEntities db = new Pubs.pubsEntities();
Pubs.author author= new Pubs.author();
author.au_id="JN";
db.authors.AddObject(author);
db.SaveChanges();
}
Cheers!