Entity Framework 4: Mapped Stored Procedure on Model with Additional Parameters - entity-framework

We've started using Entity Framework 4 for data access and have come across an issue or perhaps lack of understanding.
Our current system is heavily reliant on Stored Procedures, these procedure contain some necessary business logic so we need to continue to use these when doing Select/Insert/Update/Delete.
The issue we are having is the following:
We've mapped a table to an entity, let's say for example this is a User entity and has the following properties - UserId, FirstName, LastName
Now in our sproc to insert a user we accept FirstName, LastName, CreatedById as parameters.
As our User Entity has no CreatedById we get an error indicating that no property of our Entity can be mapped to the "CreatedById" parameter.
Now one thing we've tried is to manually add a CreatedById scalar property to our Entity, but this results in the issue that there is no Field in our User table in the data source that maps to CreatedById. In general the additional property that we'd like to pass in is not something that is stored.
Now there is potential solution to this in that we can just map the procedures to Function Imports and not bother with using the .AddObject, .DeleteObject, .SaveChanges way of manipulating our objects but that doesn't feel like the way to go about it.

that's a good question. There are few options i can tell u.
instead of mapping the entity to the table, map it a view and have the view return CreatedById and then your problem would be solved.
Second option is to create overloaded stored procedure that takes only FirstName, LastName and calls the actual stored procedure with a default value for CreatedById. You can create overloads at the database layer or create it in the model in the ssdl layer which supports inline stored procedure.
exec myproc #firstName,#LastName,null

Related

How to use Entity, Mapper, Service and Hydrator in ZF2

I am making a ZF2 app. I am using entities, mappers and services (e.g. UserEntity, UserMapper, UserService) to manage the objects/models. Properties in the entities are CamalCased (e.g. FirstName, LastName) while in the database, fields are using underscore (first_name, last_name). I will plan to use a hydrator to map the properties and db-fields when retrieving or saving. The service object (UserService) will be used to communicate with the mapper to retrieve and save data models using the mapper. The hydrator will convert the result of mapper and convert them into proper entities.
The thing I am confused is that when the service (UserService) need to provide some cirteria - for example to find all users with a specific 'last name', will the service use the database field names (last_name) or entity properties name (LastName)?
If the db field name is used in the Service, so any change in the db structure will require me to update the service also, which completely fails the reason of using the whole approach.
If you take a look at the ClassMethods:hydrate method (https://github.com/zendframework/zf2/blob/master/library/Zend/Stdlib/Hydrator/ClassMethods.php) you will see that it just copies the properties from one object to another. You have the option of converting the property names to/from camelCase but that's it.
If you change a column name in your database then you will need to change corresponding property name in your object. And vice versa. Which I believe is the crux of your question?
If you want to make table column names be independent of your method names then you need something that lets you define an actual mapping table somewhere. Change a column or method name and you only need to update the configuration mapping table.
Not a ZF2 expert so I could be wrong but it doesn't look like any of the supplied hydrators support this.
I do know that Doctrine 2 supports it.

Entity framework 4 model first using money value object

I want to use a Money value object in my application. I have found several examples of a Money datatype. But I can't figure out how to use them with EF4. I would like to store each amount as a Decimal/CurrencyCode pair (where currencycode is a string - "USD", "SEK", etc) in the database. I tried creating a complexType but I couldn't get that to work. Is this possible?
It should be definitely possible. Your complex type is just pair of decimal and string property. It is exactly what complex type are used for. Depending on your approach you must do:
Database first:
You will define your database first. Your table will contain money and varchar columns representing your new type. When you update your EDMX model from database it will include it as scalar properties to your entity. You must remove those properties. Then go to model browser and create new complex type. Return back to entity and add complex property of your new complex type. And at the end you must go to entity mapping and map your complex type to those database columns.
Here is basic tutorial from MSDN but from unknown reason they didn't include such elementary details like screenshots. Here is some video from channel9.
Model first:
This is similar to database first but you don't have to deal with database creation and mapping. It will be generated for you.
Code first (EF 4.1):
You must create separate class for your complex type and use it as property in your entity. You should not need to map it by default - mapping should be infered. If it doesn't work you can map complext type either by using ComplextTypeAttribute annotation or by defining mapping in DbModelBuilder.
I can further extend approach you need to use if you provide more details.

Entity Framework: Creating single entity from related, cascading tables

I am working with a database contains related tables for storing person address details. The following tables store the information – County, City Suburb, Address and Address Type.
The Address table holds street and house number information in addition to AddressTypeId (Associated to AddressType Table). The Address table also has a SuburbId column for the association with the Suburb table. The associations of a person’s address cascade down to the County table.
I want the Person data object to have an IList property. What would be my best approach to achieve this?
Use a stored procedure to generate the Address entity on the Entity designer.
Create a complex type and add this to the Person type as IList.
There might be some other recommended way than the above options. If there is a step-by-step example some one could point me to, that would be great.
As far your question you can write a stored procedure that gets all the address information. Have a select statement at the end of your stored procedure selecting all of the address information.
When you add this procedure entity framework(4.0 I assume)...you can create a function import and ef4 will create an complex type for return of your stored procedure. Here is a tutorial.

stored procedure mapping Entity Framework

We're using a Function Import in an EF4 model to populate an existing entity in our Model. The entity in the model has a Key field of Id which we're struggling to map as our stored procedure doesn't return an Id field. I've tried setting the value in the mapping to a literal value of 0 but that fails with an EntityCommandExecutionException and the following exception text.
The data reader is incompatible with the specified 'Candidate'. A member of the type, 'Id', does not have a corresponding column in the data reader with the same name.
Short of modifying the stored procedure to return a dummy Id field can anyone recommend what the best approach is for this as the dummy field option feels very clunky to me.
Many Thanks
If you can't return enough data to fully materialize the entity -- and the Id field is certainly going to be required for that -- then you need to change the return type on the proc to be a complex type instead of an entity.
Use another POCO class with the same structure to receive the results of the stored procedure call, here's an example:
string sp = string.Format("EXEC dbo.spComercialesAsociadosActivos {0}", idComercialPrincipal);
return ((IObjectContextAdapter)this).ObjectContext.ExecuteStoreQuery<InfoComercial>(sp);
In this case "InfoComercial" is a POCO class with the same structure as "Comercial", which is tied up to EF code first in the DBContext, then I used this independent class in the viewModel to create a disconnected "Comercial", it's not an ideal solution but will work fine until EF 5 comes with SP support.

Entity framework function import, can't load relations for functions that return entity types

I've created a function import that returns the results of a stored proceedure as one of my entities. however I can't seem to traverse my through navigation properties to access the data in other entities. I know that you can use include() for objectQueries but can't find anything that will force the EF to load my relations for entity results of function imports.
Any ideas??
Thanks in advance.
This is not possible in EF 1.0
The reason is that EF will consider stored procedure values to be just values and not navigation properites.
For example, Employee entity has multiple Order entities. In Order you have a property called EmployeeID. When the database fills your query using include statements, it creates 1 projection query in SQL to populate all of the Order data that a particular Employee could have.
So if I said
var employee = context.Employees.Include("Orders").Where(e => e.ID == 1).First();
var orders = employee.Orders;
The SQL for the first query will create a projection query which will contain orders where the EmployeeID = 1.
Now when your stored procedure runs, this can do any code behind the scenes (in otherwords it can return any set of data). So when SQL runs the stored procedure, it just runs the code in that stored procedure and does not have any knowledge that EmployeeID on Order is an FK to that property. Additionally, if your stored procedure returns an Employee entity, then you are looking at another scenario where you will not even have an OrderID to pursue.
To work around this though, you can setup your query in EF using Include statements that can mirror any stored procedure. If you use the proper mix of .Select and .Include statements you should be able to do the same thing.