views:

3339

answers:

1

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?

+5  A: 

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);
  }
 }
Michael M.
awesome solution! saved me a days worth of work at least
naspinski
Voted up. Well done.
Sako73