具有子对象的实体对象的深度复制并将其保存到DB中

本文关键字:对象 保存 DB 复制 实体 深度 | 更新日期: 2023-09-27 17:57:49

我使用的是EF4,我有一个带子实体的实体,它也有子实体,例如:

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

我想创建Object_A及其所有子项(B、C、D、E)的深度副本,并将其保存到DB中。因此创建的复制实体不能具有相同的ID。

我遵循了这个http://naspinski.net/post/Cloning-an-Entity-in-Linq-to-Entities.aspx但这对我不起作用。问题出在上

dcs.WriteObject(ms, source);

其执行从未停止。

你能告诉我我该怎么做吗?我已经欢迎另一种解决方案。

具有子对象的实体对象的深度复制并将其保存到DB中

您可以将实体的状态更改为EntityState。添加后,EF4将插入它。

您可以使用Automapper或ValueInjecter为克隆对象

  • https://github.com/AutoMapper/AutoMapper
  • http://valueinjecter.codeplex.com/

这个automapper版本片段对我有效,我还没有制作多对多关系

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; }
}

程序.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())
            );
}

应用程序配置

<connectionStrings>
  <add name="MyDb" 
connectionString="Data Source=.;Initial Catalog=MyDb;Integrated Security=True;" 
providerName="System.Data.SqlClient" />
</connectionStrings>