The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.It occurs when one attempts to associate an entity object from one data context to an entity object from another data context. With the repository pattern, there is usually one data context per repository. So if, for example, one were to query for a user
user = usersRepository.Find(userId);
and a role
role = rolesRepository.Find(roleId);
and then attempt to associate the two
user.Roles.Add(role);
one would get the aforementioned error when executing the line
usersRepository.Save()
where the Save() method wraps the SaveChanges() method of the data context.
This post describes the situation very well. It also describes some potential solutions, one of which is to share the data context across all repositories for the life of the web request. And one way to do that is to use DI--in my case, StructureMap.
Each of my repositories ultimately derives from an abstract repository base class.
public abstract class RepositoryBase
{
protected DbContainer db;
public RepositoryBase()
{
db = ObjectFactory.GetInstance<DbContainer>();
}
}
And over in the DI configuration:
ObjectFactory.Initialize(x =>
{
x.For<DbContainer>().HttpContextScoped().Use(() => new DbContainer());
// ...
});
And there we have it, folks. On a cautionary note, because all repositories share the same context, a call to a repository's Save() method will persist changes to any changed entity, not just the ones from the saving repository. This can result in unexpected behavior, so, you know, be aware.