Good afternoon-
I am developing a Silverlight application using LINQ to Entity Framework for the data access layer. My n-tier database model includes about 30 or so tables, with a number of multi-leveled parent-child relationships throughout. Recently began writing my data services and unit tests and have discovered a problem with the insert of a new record into a child table when the parent table record is already defined. Here's an abridged version of my parent and child tables:
PARENT TABLE:
Users
UserID (PK)
Email
Password
etc...
CHILD TABLE:
UserProfiles
UserProfileID (PK)
Various profile info...
UserID (FK -- Users table)
So at this point, I have the Entity Framework has already been used to create my various classes for the ORM, and I am looking to create data services for the CRUD operations on my entities. The following is sample code for my method to insert a new User (which has no parent table references):
public User CreateUser(User newUser)
{
using (var _context = new ProjectDatabase())
{
newUser.CreatedDate = DateTime.Now;
newUser.ModifiedDate = DateTime.Now;
_context.AddToUsers(newUser);
_context.SaveChanges();
}
return newUser;
}
This works just fine. I have written unit tests for it, no problem. Now, on the other hand, consider the following data service method that I have written to insert a new UserProfile object into the database. To begin with, I have a very similar data service:
public UserProfile CreateProfile(UserProfile newUserProfile)
{
using (var _context = new ProjectDatabase())
{
newUserProfile.CreatedDate = DateTime.Now;
newUserProfile.ModifiedDate = DateTime.Now;
_context.AddToUserProfiles(newUserProfile);
_context.SaveChanges();
}
return newUserProfile;
}
This code, just like the other, compiles without problem. However, my unit test consistently fails. Here is the code for my unit test:
[TestMethod]
public void UserProfileCrudTest()
{
IProfileDataService _dataService = new ProfileDataService();
// Pre-seeded data on a State for foreign key
State _myState;
using (var _context = new ProjectDatabase())
{
_myState = _context.States.First();
}
// Creating temporary User for association with new UserProfile
User _myUser = new User()
{
Email = "test",
Password = "test",
IsActive = true,
NameFirst = "test",
NameLast = "test"
};
_myUser = _dataService.CreateUser(_myUser);
Assert.IsNotNull(_myUser);
// Attempt to create new UserProfile, assigning foreign key
_myUserProfile = new UserProfile()
{
Address = "123 Main",
City = "Anywhere",
State = _myState,
PostalCode = "63021",
UserID = _myUser.UserID
};
// This call to CreateProfile throws an exception and the test fails!!
_myUserProfile = _dataService.CreateProfile(_myUserProfile);
Assert.IsNotNull(_myUserProfile);
// Remaining test code... never gets this far...
}
So at this point, my unit test throws the following exception:
Test method MyProject.DataServices.Tests.SecurityTests.UserProfileCrudTest threw exception: System.InvalidOperationException: The EntityKey property can only be set when the current value of the property is null.
As I understand it from my research so far, this somehow is tying back to the navigation property that associates the new UserProfile object with the User.UserProfiles collection on the parent table/object. But I'm not sure what steps are needed to fix the problem. Do I somehow need to attach the parent to the ObjectContext? Any assistance would be GREATLY appreciated!
Thanks, Jeff S.