title: Cloning an object and saving the clone to db causes the original object to lose relational data
body: <p>When I'm trying to clone a <code>Product</code>-object and save the clone to the database, the original object loses all it's relational data, such as <code>ProductPropertyOptionForProducts</code>, <code>IdentifierForProducts</code> and <code>InCategories</code>.</p>
  
  <p>This is the Product model:</p>
  
  <pre><code>public class Product
  {
      public int Id { get; set; }
      public int ProductGroupId { get; set; }
      public int ProductGroupSortOrder { get; set; }
  
      [Required, MaxLength(30), MinLength(4)]     public string Title { get; set; }
      [MaxLength(200)]                            public string Info { get; set; }
      [MaxLength(4000)]                           public string LongInfo { get; set; }
      [Required, DataType(DataType.Currency)]     public decimal Price { get; set; }
                                                  public int Weight { get; set; }
                                                  public int ProductTypeId { get; set; }
      public ICollection&lt;ProductImage&gt; Images { get; set; }
  
      // Selected property options for this product
      public ICollection&lt;PropertyOptionForProduct&gt; ProductPropertyOptionForProducts { get; set; }
  
      // A product can have multiple identifiers (EAN, ISBN, product number, etc.)
      public ICollection&lt;IdentifierForProduct&gt; IdentifierForProducts { get; set; }
  
      public ProductType Type { get; set; }
      public ICollection&lt;FrontPageProduct&gt; InFrontPages { get; set; }
      public ICollection&lt;ProductInCategory&gt; InCategories { get; set; }
  }
  </code></pre>
  
  <p>Some of the related models:</p>
  
  <pre><code>public class ProductInCategory
  // A linking table for which products belongs to which categories
  {
      public int Id { get; set; }
      public int ProductId { get; set; }
      public int ProductCategoryId { get; set; }
      public int SortOrder { get; set; }
  
      // Nav.props.:
      public Product Product { get; set; }
      public ProductCategory ProductCategory { get; set; }
  }
  
  public class PropertyOptionForProduct
  {
      public int Id { get; set; }
      public int ProductId { get; set; }
      public int ProductPropertyId { get; set; }
      public int ProductPropertyOptionId { get; set; }
  
      // Nav.props.
      public Product Product { get; set; }
      public ProductPropertyOption ProductPropertyOption { get; set; }
  }
  
  public class IdentifierForProduct
  {
      public int Id { get; set; }
      public int ProductId { get; set; }
      public int ProductIdentifierId { get; set; }
      [StringLength(30), MaxLength(30)]
      public string Value { get; set; }
  
      public ProductIdentifier ProductIdentifier { get; set; }
      public Product Product { get; set; }
  }
  </code></pre>
  
  <p>The original is loaded like this:</p>
  
  <pre><code>public async Task&lt;Product&gt; GetProduct(int Id)
  {
      Product DbM = await _context.Products
          .Include(ic =&gt; ic.InCategories)
              .ThenInclude(pc =&gt; pc.ProductCategory)
          .Include(t =&gt; t.Type)
              .ThenInclude(iit =&gt; iit.Identifiers) //ProductIdentifiersInTypes
                  .ThenInclude(i =&gt; i.Identifier) // ProductIdentifiers
                      .ThenInclude(ifp =&gt; ifp.ProductIdentifiers) // IdentifiersForProducts
          .Include(t =&gt; t.Type)
              .ThenInclude(pit =&gt; pit.Properties) // ProductPropertiesInTypes
                  .ThenInclude(p =&gt; p.Property) // ProductProperties
                      .ThenInclude(po =&gt; po.Options) // ProductPropertyOptions
          .Include(p =&gt; p.ProductPropertyOptionForProducts)
          .Where(p =&gt; p.Id == Id)
          .SingleOrDefaultAsync();
      return DbM;
  }
  </code></pre>
  
  <p>This is the clone-method:</p>
  
  <pre><code>private async Task&lt;Product&gt; MakeClone(Product Original)
  {
      Product Clone = new Product
      {
          ProductGroupId = Original.ProductGroupId,
          ProductGroupSortOrder = Original.ProductGroupSortOrder + 1,
          IdentifierForProducts = Original.IdentifierForProducts,
          Images = Original.Images,
          InCategories = Original.InCategories,
          Info = Original.Info,
          InFrontPages = Original.InFrontPages,
          LongInfo = Original.LongInfo,
          Price = Original.Price,
          ProductPropertyOptionForProducts = Original.ProductPropertyOptionForProducts,
          ProductTypeId = Original.ProductTypeId,
          Title = Original.Title,
          Type = Original.Type,
          Weight = Original.Weight
      };
      _context.Add(Clone);
      await _context.SaveChangesAsync();
      return Clone; // and go to the Edit-view.
  }
  </code></pre>
  
  <p>Now, the clone has all the properties of the original product, but the original has been stripped of all of it's relational data. In the database, it looks like the clone's relational data has replaced the original's ones.</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>In accordance to Georg's answer, I changed my <code>MakeClone()</code>-method to this:</p>
  
  <pre><code>private Product MakeClone(Product Original)
  {
      List&lt;IdentifierForProduct&gt; identifiers = Original
              .IdentifierForProducts
              .Select(i =&gt; CloneIdentifierForProduct(i))
              .ToList();
      List&lt;PropertyOptionForProduct&gt; propertyOptions = Original
              .ProductPropertyOptionForProducts
              .Select(o =&gt; ClonePropertyOptionForProduct(o))
              .ToList();
      List&lt;ProductInCategory&gt; inCategories = Original
              .InCategories
              .Select(c =&gt; CloneProductInCategory(c))
              .ToList();
      List&lt;FrontPageProduct&gt; inFrontPages = Original
              .InFrontPages
              .Select(f =&gt; CloneFrontPageProduct(f))
              .ToList();
      List&lt;ProductImage&gt; images = Original.Images.Select(i =&gt; CloneProductImage(i)).ToList();
      Product Clone = new Product
      {
          ProductGroupId = Original.ProductGroupId,
          ProductGroupSortOrder = Original.ProductGroupSortOrder + 1,
          Info = Original.Info,
          LongInfo = Original.LongInfo,
          Price = Original.Price,
          ProductTypeId = Original.ProductTypeId,
          Title = Original.Title,
          Type = Original.Type,
          Weight = Original.Weight,
          IdentifierForProducts = identifiers,
          ProductPropertyOptionForProducts = propertyOptions,
          InCategories = inCategories,
          InFrontPages = inFrontPages,
          Images = images
      };
      _context.Add(Clone);
      // fix FKs
      foreach (var ifp in Clone.IdentifierForProducts) ifp.ProductId = Clone.Id;
      foreach (var ofp in Clone.ProductPropertyOptionForProducts) ofp.ProductId = Clone.Id;
      foreach (var pic in Clone.InCategories) pic.ProductId = Clone.Id;
      foreach (var fpp in Clone.InFrontPages) fpp.ProductId = Clone.Id;
      foreach (var pi in Clone.Images) pi.ProductId = Clone.Id;
      // Lagre klonen i databasen:
      _context.SaveChangesAsync();
      return Clone;
  }
  </code></pre>
  
  <p>... and added separate methods for cloning each of the linked data (I don't think I need to show all five methods):</p>
  
  <pre><code>private IdentifierForProduct CloneIdentifierForProduct(IdentifierForProduct ifp)
  {
      IdentifierForProduct IFP = new IdentifierForProduct
      {
          Product = ifp.Product,
          ProductId = ifp.ProductId,
          ProductIdentifier = ifp.ProductIdentifier,
          ProductIdentifierId = ifp.ProductIdentifierId,
          Value = ifp.Value
      };
      return IFP;
  }
  </code></pre>
  
  <p>Now I'm getting <code>ArgumentNullException</code> on the creation of the child Lists.</p>
  
  <p>Could it have something to do with the fact that for example <code>IdentifierForProduct</code> also has a child property (which I also want to clone)?</p>