0

I am using EF4 and I have entity with child entities which has also child entities, f.e. :

Object_A    N to M    to Object_B
Object_A    1 to N    Object_C
Object_C    1 to N    Object_D
Object_D    1 to N    Object_E

I want to create deep copy of Object_A with its all childs (B, C, D, E) and save it into DB. So created copied entities cannot have the same IDs.

I have followed this http://naspinski.net/post/Cloning-an-Entity-in-Linq-to-Entities.aspx but it wont works for me. The problem is in line

dcs.WriteObject(ms, source);

which execution never stops.

Can you tell me please how can I do this ? I already welcome another solution.

rene
  • 41,474
  • 78
  • 114
  • 152
Peter R.
  • 85
  • 1
  • 4
  • 15

2 Answers2

0

You could change the state of your entities to EntityState.Added, that way EF4 would insert it.

Patrick
  • 409
  • 2
  • 10
0

You could use Automapper or ValueInjecter to clone the objects for you

This automapper version snippet works for me, I haven't made the many-to-many relation

Context.cs

public class Context : DbContext    
{
    public Context() : base("MyDb") { }
    public DbSet<A> As { get; set; }        
    public DbSet<C> Cs { get; set; }
    public DbSet<D> Ds { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {            
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<C>().HasKey(a => a.Id);
        modelBuilder.Entity<C>().HasKey(a => a.Id).HasOptional(a => a.A)
            .WithMany(b => b.Cs).HasForeignKey(c => c.AId);
        modelBuilder.Entity<D>().HasKey(a => a.Id).HasOptional(a => a.A)
            .WithMany(b => b.Ds).HasForeignKey(c => c.AId);
    }    
}    
public class A {
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<C> Cs { get; set; }
    public virtual ICollection<D> Ds { get; set; }
}                
public class C {
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual A A { get; set; }        
    public int? AId { get; set; }
}
public class D {
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual A A { get; set; }        
    public int? AId { get; set; }
}

Program.cs

// using System.Data.Entity;
using (var db = new Context())
{
    // Run these once per lifetime
    AutoMapper.Mapper.CreateMap<A, A>();
    AutoMapper.Mapper.CreateMap<C, C>();
    AutoMapper.Mapper.CreateMap<D, D>();

    var myObject = new A { Name = "joe", 
        Cs = new List<C> { new C { Name = "c1" } }, 
        Ds = new List<D> { new D { Name = "d1" } } 
    };
    db.As.Add(myObject);
    db.SaveChanges();

    var clonedObject = AutoMapper.Mapper.Map<A, A>(myObject);    

    db.As.Add(clonedObject);
    db.SaveChanges();

    db.As
        .Include(a => a.Cs)
        .Include(a => a.Ds)
        .ToList()
        .ForEach(a => Console.WriteLine("{0} - Cs: {1}, Ds: {2}",
            a.Name, a.Cs.Count(), a.Ds.Count())
            );
}

App.config

<connectionStrings>
  <add name="MyDb" 
connectionString="Data Source=.;Initial Catalog=MyDb;Integrated Security=True;" 
providerName="System.Data.SqlClient" />
</connectionStrings>
Kunukn
  • 2,136
  • 16
  • 16