Entity framework saving child objects - frameworks

Im pretty new to entity framework and am having some trouble adjusting. Like all things, in the beginning i saw how much simpler it made my life for CRUD operations and thought it was great. However as my object model grew slightly more complex i began to have more and more issues with it.
Although I have managed to find answers to virtually all my questions by searching on here to date, my current one stumps me.
I have two entities which are linked by a 1 to 1/0 relationship. I cant post images yet so please fogive my dodgy drawing below:
Person (id, name, address, dob, etc. etc.)
Spouse (id, name, address, dob, etc. etc.)
Whilst the actual is more complex I don't think its part of my problem.
Now, seeing this is a 1 to 0/1 relationship either a person has 1 spouse, or they have 0. If i construct my object by:
Person person = new Person();
person.Spouse = new Spouse();
person.Spouse = spouse;
(imagine property setting included)
and then save it. It works a treat. I can then load it again, edit it, etc. etc. Life is grand.
Where I run into problems is where I save a person (no spouse), and then load the person for editing at a later stage and try to attach a spouse. When i get to my container.Attach(person); call, it throws the following exception: "An object with a temporary EntityKey value cannot be attached to an object context."
Now, I am extremely confident this is due to the way im adding the spouse, ie:
Person person = LoadPerson(id);
Spouse spouse = new Spouse();
person.Spouse1 = spouse;
The problem im seeing is im trying to now associate a child entity which was not previously associated. I have done a lot of searching on the error message but generally it seems to relate to the object context. Also i have found a work around (from the results i have found). If I use a 1 to many relationship and do Person.Spouses.Add(spouse) it works fine. However im hesitant to do so as the relationship is not logical (in this country anyway...). Im sure its a simple answer which i have obviously overlooked in the results i have seen (i highly doubt im the first to try and do this...) but nothing i have tried seems to work.
Any help would be highly appreciated...

You probably need to add the Spouse to the Context first
Context.Spouses.Add(spouse);
Before you attach it to the Person.

Related

How to build complex relationships in CoreData correctly?

I am dealing with CoreData, for training, I decided to create a small application for recording user income and expenses. CoreData tutorials all contain To-Do-List examples, and I haven't found any good examples that would help me.
// MARK: - Grammar
// I want to apologize for grammatical errors in the text. Unfortunately,
// English is not my native language, so in some places I used a translator.
If something is not clear, I will definitely try to explain it again.
When I began to think over how I would implement the application, I assumed that the most convenient way would be to save all user operations and make calculations in the application in the right places. So far, abstract, since It seems to me that this has little to do with the question, if you need to be more precise, I can provide a complete idea.
So, I'm going to save the user model, which will have the following data:
User operations (Operation type) - all operations will be saved, each operation includes the category for which the operation was performed, as well as the amount in currency.
User-selected categories (Category Type) - Categories that will be used for expenses or income when adding an operation.
Wallets (Type Wallet) - User's wallets, Everything is simple, the name, and the balance on it.
Budget Units (BudgetUnit Type) - These are user budgets, contains a category, and a budget for it. For example: Products - 10.000 $
When I started building dependencies in CoreData, I got a little strange behavior.
That is, the user has a relationship on the same category model as the Budget Unit and Operation. Something tells me that it won't work that way.
I want the user categories to be independent, he selected them, and I'm going to display them on the main screen, and each operation will have its own category model
In the picture above, the category model is used 3 times, the same model.
This is roughly how I represent the data structure that I would like to see. Different models have their own category model, independently of the others.
I think it could be implemented using 3 different models with the same values, but it seems to me that this approach is considered wrong.
So how do you properly implement the data model so that everything works as expected? I would be grateful for any help!
--- EDIT ---
As a solution to the problem, I can create multiple entities as Category (Example bellow)
But I don't know if this is good practice
I looked into several other open source projects and saw a solution to the problem.
I hope this helps someone in the future.
There is no need to save the categories for the user, you can simply save the categories in the application by adding the IsSelected and ID parameter to them in order to change these parameters when you select a category, and immediately understand which ones you need to display.
For budgets and operations (transactions) , we only need to save the category ID to immediately display the correct one.
For example:
Thanks #JoakimDanielson and #Moose for helping. It gave me a different view of the subject.

Issue with Relationships in Access

I am currently working within Access 2013. I have a simple task that has been really driving me crazy these past few days, as I thought my relationships where correct. But when adding more data into the database I saw that there was a major problem.
Within the database everything is working fine between tblPersonal Information and tblPosition Applied for. The problem that I am running into is trying to successfully create the one to many relationship between tblPosition Applied for and tblOffer
I am trying to make it so that:
one person can apply to many positions (one to many)
one position that each person applies for can have one contingent offer (one to many) "the root of the problem that I am having"
Is their a field that I need to add, or create another table holding just the Personal ID to link tblPosition Applied for and tblOffer? I am really lost on this any help would be greatly appreciated.
If a Position_applied_For can have one-to-many offers, then you need to create a related field in tbl_Offer, just as you did for the one-to-many relationship between tbl_Personal_Information and tblPosition_Applied_For. Change tbl_Offer.Personal_ID to tbl_Offer.Position_Applied_For and relate it back to tblPosition_Applied_For.ID.
Right now there are no fields that are related except Personal_ID in the offers and applied tables. Essentially, there would be no way to distinguish if Person A applied for Job 1 and Job 2, and received an offer for Job 2.
In your tbl_Offer, there should be a Position_ID that relates to the Position. Also, assuming that the offer is only valid for one person, there is no need for tbl_Offer to contain a Personal_ID field, as it would be related through the tblPosition_Applied_For.

In what scenarios would I need to use the CREATEREF, DEREF and REF keywords?

This question is about why I would use the above keywords. I've found plenty of MSDN pages that explain how. I'm looking for the why.
What query would I be trying to write that means I need them? I ask because the examples I have found appear to be achievable in other ways...
To try and figure it out myself, I created a very simple entity model using the Employee and EmployeePayHistory tables from the AdventureWorks database.
One example I saw online demonstrated something similar to the following Entity SQL:
SELECT VALUE
DEREF(CREATEREF(AdventureWorksEntities3.Employee, row(h.EmployeeID))).HireDate
FROM
AdventureWorksEntities3.EmployeePayHistory as h
This seems to pull back the HireDate without having to specify a join?
Why is this better than the SQL below (that appears to do exactly the same thing)?
SELECT VALUE
h.Employee.HireDate
FROM
AdventureWorksEntities3.EmployeePayHistory as h
Looking at the above two statements, I can't work out what extra the CREATEREF, DEREF bit is adding since I appear to be able to get at what I want without them.
I'm assuming I have just not found the scenarios that demostrate the purpose. I'm assuming there are scenarios where using these keywords is either simpler or is the only way to accomplish the required result.
What I can't find is the scenarios....
Can anyone fill in the gap? I don't need entire sets of SQL. I just need a starting point to play with i.e. a brief description of a scenario or two... I can expand on that myself.
Look at this post
One of the benefits of references is that it can be thought as a ‘lightweight’ entity in which we don’t need to spend resources in creating and maintaining the full entity state/values until it is really necessary. Once you have a ref to an entity, you can dereference it by using DEREF expression or by just invoking a property of the entity
TL;DR - REF/DEREF are similar to C++ pointers. It they are references to persisted entities (not entities which have not be saved to a data source).
Why would you use such a thing?: A reference to an entity uses less memory than having the DEFEF'ed (or expanded; or filled; or instantiated) entity. This may come in handy if you have a bunch of records that have image information and image data (4GB Files stored in the database). If you didn't use a REF, and you pulled back 10 of these entities just to get the image meta-data, then you'd quickly fill up your memory.
I know, I know. It'd be easier just to pull back the metadata in your query, but then you lose the point of what REF is good for :-D

Why does my Entity Framework query return a record twice?

I have two tables, one with Contacts (people) and another with Addresses.
Gregory Alderson has one Contact entry and two Address entries.
This is the code:
that returns two a records for Gregory Alderson:
If I leave LazyLoadingEnable set to ‘true’, it does the same thing but both records contain both addresses:
The book I’m learning from (Programming Entity Framework 2nd edition – good book BTW) explained that LazyLoading is disabled so the Count method does not impact the results, but so far has not explained why it would do so.
Can someone explain to me why I get two records with LazyLoading turned off, and two records (both with both addresses) with LazyLoading turned on?
A good way to get a better understanding of what's going on is run up Query Analyzer and watch what SQL statements are executed against the db or better yet get a copy of Ayende's EF Profiler.
Essentially with eager loading you need to be more explicit on what related entities you want returned. This is done using the Include method on the context object. Without lazy loading enabled you're making a single hit against the db and then evaluating only against the locally held data rather than making another request to the db for further data used in the Count().
The issue here seems to be due to what you're selecting. Specifically:
select new {a, a.Contact}
Contact is actually a navigation property of a in this case. When you select a, you're selecting everything on a, including Contact. Also selecting a.Contact means you get contact twice.
With lazy loading enabled you don't have to select it. If you select a and then simply use a.Contact somewhere else in your code, EF will go load it for you. The "lazy" in lazy loading is that it's not loaded unless you actually try to use it. With lazy loading on, you just need this:
select a
With lazy loading off, that doesn't happen. But you still don't want to select it. Instead you'd use Include:
from a in context.Addresses.Include("Contact") select a
That tells EF that you always want it to load the Contact navigation property and to do so immediately. It'll be available right away and will still be available if you dispose of the context (which isn't the case with lazy loading).
I suspect the problem here is that by selecting all of a AND a property of a, you're getting a weird side effect.
The OP's question, summed up in the last two paragraphs, was:
The book I’m learning from (Programming Entity Framework 2nd edition – good book BTW) explained that LazyLoading is disabled so the Count method does not impact the results, but so far has not explained why it would do so.
Can someone explain to me why I get two records with LazyLoading turned off, and two records (both with both addresses) with LazyLoading turned on?
The part about the effects of LazyLoading on Count() was explained by Daz. But neither Daz nor Tridus explained why the OP was getting two Contact records for Gregory Anderson in the output regardless of LazyLoading. That is the question that I will answer here.
The problem is that the iteration was essentially happening over Addresses. That is, the outer foreach loop was executing once for each Address in Canada. So because Gregory Anderson has two addresses in Canada, the loop is executed twice for him.
Note that if Gregory Anderson also had an address in the US, the loop would still be executed twice, but all three addresses would be printed out, not just the addresses in Canada.
If the intention was actually to list each Contact once and then list each Address for that Contact, a more appropriate design would be the following:
var contacts = context.Contacts
.Where(c => c.Addresses.Any(a => a.CountryRegion == "Canada"));
foreach (var c in contacts)
{
Console.WriteLine("{0} {1}, Addresses: {2}",
c.FirstName.Trim(),
c.LastName.Trim(),
c.Addresses.Count());
foreach (var a in c.Addresses)
{
Console.WriteLine("...{0}, {1}\n", a.Street1.Trim(), a.City.Trim());
}
}
(I tried to keep the code as close to identical as I could, but I couldn't think of how to write the query using query syntax, so I used LINQ syntax because I'm much more familiar with it...)
This code will result in a distinct list of Contacts being returned from the database and then each Contact will be output one time along with each of the child Addresses.
Hope that helps someone who might be dealing with this and didn't find the other answers helpful on this aspect.

How to keep track of objects deleted from an ObservableCollection in CRUD scenarios?

In our multi-tier business application we have ObservableCollections of Self-Tracking Entities that are returned from service calls.
The idea is we want to be able to get entities, add, update and remove them from the collection client side, and then send these changes to the server side, where they will be persisted to the database.
Self-Tracking Entities, as their name might suggest, track their state themselves.
When a new STE is created, it has the Added state, when you modify a property, it sets the Modified state, it can also have Deleted state but this state is not set when the entity is removed from an ObservableCollection (obviously). If you want this behavior you need to code it yourself.
In my current implementation, when an entity is removed from the ObservableCollection, I keep it in a shadow collection, so that when the ObservableCollection is sent back to the server, I can send the deleted items along, so Entity Framework knows to delete them.
Something along the lines of:
protected IDictionary<int, IList> DeletedCollections = new Dictionary<int, IList>();
protected void SubscribeDeletionHandler<TEntity>(ObservableCollection<TEntity> collection)
{
var deletedEntities = new List<TEntity>();
DeletedCollections[collection.GetHashCode()] = deletedEntities;
collection.CollectionChanged += (o, a) =>
{
if (a.OldItems != null)
{
deletedEntities.AddRange(a.OldItems.Cast<TEntity>());
}
};
}
Now if the user decides to save his changes to the server, I can get the list of removed items, and send them along:
ObservableCollection<Customer> customers = MyServiceProxy.GetCustomers();
customers.RemoveAt(0);
MyServiceProxy.UpdateCustomers(customers);
At this point the UpdateCustomers method will verify my shadow collection if any items were removed, and send them along to the server side.
This approach works fine, until you start to think about the life-cycle these shadow collections. Basically, when the ObservableCollection is garbage collected there is no way of knowing that we need to remove the shadow collection from our dictionary.
I came up with some complicated solution that basically does manual memory management in this case. I keep a WeakReference to the ObservableCollection and every few seconds I check to see if the reference is inactive, in which case I remove the shadow collection.
But this seems like a terrible solution... I hope the collective genius of StackOverflow can shed light on a better solution.
EDIT:
In the end I decided to go with subclassing the ObservableCollection. The service proxy code is generated so it was a relatively simple task to change it to return my derived type.
Thanks for all the help!
Instead of rolling your own "weak reference + poll Is it Dead, Is it Alive" logic, you could use the HttpRuntime.Cache (available from all project types, not just web projects).
Add each shadow collection to the Cache, either with a generous timeout, or a delegate that can check if the original collection is still alive (or both).
It isn't dreadfully different to your own solution, but it does use tried and trusted .Net components.
Other than that, you're looking at extending ObservableCollection and using that new class instead (which I'd imagine is no small change), or changing/wrapping UpdateCustomers method to remove the shadow collection form DeletedCollections
Sorry I can't think of anything else, but hope this helps.
BW
If replacing ObservableCollection is a possibility (e.g. if you are using a common factory for all the collections instances) then you could subclass ObservableCollection and add a Finalize method which cleans up the deleted items that belongs to this collection.
Another alternative is to change the way you compute which items are deleted. You could maintain the original collection, and give the client a shallow copy. When the collection comes back, you can compare the two to see what items are no longer present. If the collections are sorted, then the comparison can be done in linear time on the size of the collection. If they're not sorted, then the modified collection values can be put in a hash table and that used to lookup each value in the original collection. If the entities have a natural id, then using that as the key is a safe way of determining which items are not present in the returned collection, that is, have been deleted. This also runs in linear time.
Otherwise, your original solution doesn't sound that bad. In java, a WeakReference can register a callback that gets called when the reference is cleared. There is no similar feature in .NET, but using polling is a close approximation. I don't think this approach is so bad, and if it's working, then why change it?
As an aside, aren't you concerned about GetHashCode() returning the same value for distinct collections? Using a weak reference to the collection might be more appropriate as the key, then there is no chance of a collision.
I think you're on a good path, I'd consider refactoring in this situation. My experience is that in 99% of the cases the garbage collector makes memory managment awesome - almost no real work needed.
but in the 1% of the cases it takes someone to realize that they've got to up the ante and go "old school" by firming up their caching/memory management in those areas. hats off to you for realizing you're in that situation and for trying to avoid the IDispose/WeakReference tricks. I think you'll really help the next guy who works in your code.
As for getting a solution, I think you've got a good grip on the situation
-be clear when your objects need to be created
-be clear when your objects need to be destroyed
-be clear when your objects need to be pushed to the server
good luck! tell us how it goes :)