Ok, so in this example I have a parent entity called Template. A Template always has a type. The type is an FK that is very likely to already exist. The problem comes when creating a new Template and adding to it the type. Once the type is added and you go to add the Template you receive an error. Which error you receive depends on the approach. Does anyone know how to work with this kind of situation?
public static void AddTemplate(Template template)
{
using (TheEntities context = new TheEntities())
{
//if (template.TemplateType.EntityKey != null)
//{
// context.Attach(template.TemplateType);
//}
context.AddToTemplates(template);
context.SaveChanges();
context.RemoveTracking(template);
}
}
I have tried both attempting to attach the existing key and not. The call at the bottom to RemoveTracking is simply an extension to call detach on template and any sub entities that may have been loaded.
Here is the unit test.
[TestMethod]
public void CanAddAndDeleteATemplate()
{
Template template = new Template();
template.Name = "Test";
template.Description = "Test";
TemplateType type = TemplateManager.FindTemplateTypeByName("Round");
if (type == null)
{
type = new TemplateType();
type.Name = "Round";
}
template.TemplateType = type;
TemplateManager.AddTemplate(template);
template = TemplateManager.FindTemplateByID(template.TemplateID);
Assert.IsNotNull(template);
TemplateManager.DeleteTemplate(template);
template = TemplateManager.FindTemplateByID(template.TemplateID);
Assert.IsNull(template);
}
The unit test works perfectly assuming a Template Type of "Round" does not exist yet. I am starting to wonder if this kind of stuff is possible in a detached environment.
UPDATE
Ok I changed my code for AddTemplate to this and now it works..
public static void AddTemplate(Template template)
{
using (TheEntities context = new TheEntities())
{
if (template.TemplateType.EntityKey != null)
{
TemplateType type = template.TemplateType;
template.TemplateType = null;
context.AttachTo("TemplateTypes", type);
template.TemplateType = type;
}
context.AddToTemplates(template);
context.SaveChanges();
context.RemoveTracking(template);
}
}
So for all existing child entities that are added to a new parent by a client will have to have this kind of work done on them when they are ready to be persisted. Is there a cleaner way to do this? Maybe something a bit more generic?
Following are the two steps that needs to be taken with disconnected entity graph or even a single disconnected entity. Attach entities with the new context instance and make context aware about these entities. Set appropriate EntityStates to these entities manually.
There are 2 ways (connected and disconnected) when persisting an entity with the Entity Framework. Both ways have their own importance. In the case of a connected scenario the changes are tracked by the context but in the case of a disconnected scenario we need to inform the context about the state of the entity.
Detached is the default state of a newly created entity because the context can't track the creation of any object in your code. This is true even if you instantiate the entity inside a using block of the context. Detached is even the state of entities retrieved from the database when tracking is disabled.
Because an open connection to the database consumes a valuable resource, the Entity Framework opens and closes the database connection only as needed. You can also explicitly open the connection. For more information, see Managing Connections and Transactions. Once in each application domain.
Changing the code to this allows for the object state manager to track the change and allow for the Template to be added.
public static void AddTemplate(Template template)
{
using (TheEntities context = new TheEntities())
{
if (template.TemplateType.EntityKey != null)
{
TemplateType type = template.TemplateType;
template.TemplateType = null;
context.AttachTo("TemplateTypes", type);
template.TemplateType = type;
}
context.AddToTemplates(template);
context.SaveChanges();
context.RemoveTracking(template);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With