LINQ to SQL: To Attach or Not To Attach
- by bradhe
So I'm have a really hard time figuring out when I should be attaching to an object and when I shouldn't be attaching to an object. First thing's first, here is a small diagram of my (very simplified) object model.
Edit: Okay, apparently I'm not allowed to post images...here you go: http://i.imgur.com/2ROFI.png
In my DAL I create a new DataContext every time I do a data-related operation. Say, for instance, I want to save a new user. In my business layer I create a new user.
var user = new User();
user.FirstName = "Bob";
user.LastName = "Smith";
user.Username = "bob.smith";
user.Password = StringUtilities.EncodePassword("MyPassword123");
user.Organization = someOrganization; // Assume that someOrganization was loaded and it's data context has been garbage collected.
Now I want to go save this user.
var userRepository = new RepositoryFactory.GetRepository<UserRepository>();
userRepository.Save(user);
Neato! Here is my save logic:
public void Save(User user)
{
if (!DataContext.Users.Contains(user))
{
user.Id = Guid.NewGuid();
user.CreatedDate = DateTime.Now;
user.Disabled = false;
//DataContext.Organizations.Attach(user.Organization);
DataContext.Users.InsertOnSubmit(user);
}
else
{
DataContext.Users.Attach(user);
}
DataContext.SubmitChanges();
// Finished here as well.
user.Detach();
}
So, here we are. You'll notice that I comment out the bit where the DataContext attachs to the organization. If I attach to the organization I get the following exception:
NotSupportedException: An attempt has been made to Attach or Add an
entity that is not new, perhaps having
been loaded from another DataContext.
This is not supported.
Hmm, that doesn't work. Let me try it without attaching (i.e. comment out that line about attaching to the organization).
DuplicateKeyException: Cannot add an entity with a key that is already
in use.
WHAAAAT? I can only assume this is trying to insert a new organization which is obviously false.
So, what's the deal guys? What should I do? What is the proper approach? It seems like L2S makes this quite a bit harder than it should be...