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>