Entity Framework: Creating single entity from related, cascading tables - frameworks

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.

Related

EF 6 Remove entity connected to read only view

I have two entities: one based on normal DB table and another base on DB View. They are connected one to many, like this:
Entity City do not have store procedures mapped because for entity Country it is enough to have read only collection of Cities.
And cascade rule is not set.
But then I want to delete Country instance which have some Cities loaded I've received the following error:
Unable to update the EntitySet because it has a
DefiningQuery and no 'DeleteFunction' element exists in the
'ModificationFunctionMapping' element to support the current
operation.
Which forcing me to create dummy stored procedure on DB and use it as Delete function, but it is an ugly solution.
Is there any better solution?

How can I replicate core data model using a traditional relational database?

I have my app using core data with the data model below. However, I'm switching to a standard database with columns and rows. Can anyone help me with setting up this new database schema?
First of all you need to create tables for each of the Entities and their attributes (note I added "id" to each of the tables for relationships):
Routine (name, timestamp, id)
Exercise - this looks like a duplicate to me, so leaving one only here (muscleGroup, musclePicture, name, timeStamp, id)
Session (timeStamp, id)
Set (reps, timeStamp, unit, weight, id)
Now that you have tables that describe each of the entities, you need to create tables that will describe the relationships between these entities - as before table names are in capitals and their fields are in parenthesis:
RoutineExercises (routine_id, exercise_id)
SessionExercises (session_id, exercise_id)
ExerciseSets (exercise_id, set_id)
That's it! Now if you need to add an exercise to a routine, you simply:
Add an entry into Exercise table
Establish the relationship by adding a tuple into RoutineExercises table where routine_id is your routine ID and exercise_id is the ID of the newly created entry in the Exercise table
This will hold true for all the rest of the relationships.
NOTE: Your core data model has one-to-many and many-to-many relationships. If you want to specifically enforce that a relationship is one-to-many (e.g. Exercise can only have 1 routine), then you will need to make "exercise_id" as the index for the RoutineExercises table. If you want a many-to-many relationships to be allowed (i.e. each exercise is allowed to have multiple routines), then set the tuple of (routine_id, exercise_id) as the index.

Zend Framework Doctrine insert one-to-many

Amongst order tables i have a Customers table and Addresses table. A customer can have many addresses so I have setup a one-to-many relationship in a yaml file. The thing is the id for the Customers table is auto generated so I would not know the Customers_id until after the insert however, the Customers_id is a foreign key in the Addresses table.
The information for both tables is captured on the same form although each set of data is in a subform. How do I get Doctrine to insert the data into the Customers table then fetch the Customers_id just entered and use it as the foreign key for the Addresses table.
Hope I have been able to get the essence of the question across.
BTW I am using Zend Framework and Doctrine 1.2.3
Once you do $customer->save(), you may use $customer->id (if "id" is the Customers_id column name of your customer table) to get the Customers_id to put in Addresses table.
Once you do $customer->save(); the following statement $customer->identifier(); should give you the id.
Assuming you are using Doctrine 1.x you could do the following:
$cusomer->Address[] = $address; // Assign multiple addresses in this manner
$customer->save();
This will first save the customer details to the db and then store the address data. Since doctrine understands the relationship between customer and address, the ORM will insert the customer id in the address table. Further this will be run within a transaction by Doctrine which ensures that if one of the operations fail the entire transaction will be rolled back.

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

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

ADO.NET Entity Data Model: Auto-generated classes

I have a table structure like the following:
Companies Addresses
********* *********
ID ID
AddressID ...
BillingAddressID ...
AddressID and BillingAddressID are foreign keys which are present in the Addresses table. When I generate my model based on this table instead of getting what I would expect to get (the AddressID, BillingAddressID) in the company class. I get the following:
public Addresses Addresses { .. }
public global::System.Data.Objects.DataClasses.EntityReference<Addresses> AddressesReference { .. }
public Addresses Addresses1 { .. }
public global::System.Data.Objects.DataClasses.EntityReference<Addresses> Addresses1Reference { .. }
It seems to be replacing BillingAddress with Addresses1 (not quite sure why that's happening). Also this seems to be common wherever I have a foreign key i.e. instead of the ID I get Table then the TableReference.
I think I can see whats happening i.e. instead of giving me the ID alone, it will be doing a lookup and finding the actual record the ID refers to. However, I am not quite sure what the TableReference field is for....
Can explain this a little better for me?
Thanks in advance.
Relationships are represented as objects in Entity Framework, in the same manner as entities. Even if you are not going to work a lot directly on them, relationship object are first class citizens in EF. EF kreates ObjectStateEntry objects for tracking changes on relationships, just like it does it for entities.
That is why there are two references. First one, AddressesReference is a reference to the relationship object, not the exact entity, and second one Addresses is actual entity.
Peter Chan (link), and Julia Lerman in her book Programming Entity Framework, 1st Edition, say that understanding how relationship works in EF is very important. Also they mention that this is first thing that is confusing developer when they start using EF.
The foreign keys are replaced by a reference to the entity (collection) the foreign key points to.
So to add an address to a company you would do something like:
Address a = new Address();
// ... set variables for address here
currentCompany.Addresses = a;
// or, the other way round (for collections)
a.Companies.Add(currentCompany);
EF uses the table names as the reference point when it builds the model and this is why you see "Addresses" and Addresses1". You can open up the entity model in the GUI format and click on each of the associations. These can be renamed to whatever you like, just click on the reference, view the mapping, ensure it is the one that maps "BillingAddressID" to "BillingAddressID" and rename that reference to "BillingAddress".
Note the current "Addresses" reference may be the one mapping the "BillingAddressID" so you have to check both references.
It would probably be best to change the mapping for "AddressID" to be "Address" instead of "Addresses" if it is a one to one mapping as well.