3

我想要的只是创建一个对象的精确副本。

我有一堂课

[Serializable]
public class Project 
{
    public int Id { get; set; }
    public String Name { get; set; }

    //navigational fields..
    public virtual List<BusinessRequirement> BusinessRequirements { get; set; }
 }

和另一个

[Serializable]
public class BusinessRequirement 
{
   public int Id { get; set; }
   public String Name { get; set; }
   public String Description { get; set; }
   public virtual List<Project> Projects { get; set; }
}

所以我在某处配置了多对多的黑白关系ProjectBusinessRequirement如下所示:

HasMany(s => s.BusinessRequirements)
           .WithMany(s => s.Projects)
           .Map(m =>
            {
                   m.MapLeftKey("ProjectId");
                   m.MapRightKey("BusinessRequirementId");
                   m.ToTable("ProjectBusinessRequirementMapping");

            });

而且我也让我的 dbcontext 静态,即

public static class DataLayer
{
    public static MyDbContext db;
}

现在,我所做的只是尝试复制Projectie的对象

public Project Clone(Project source)
{

     Project  target = new Project();
     target.Name = source.Name;
     //1.
     // target = source;    

     //2.
     target.BusinessRequirements = new List<BusinessRequirement>();
     foreach(BusinessRequirement br in source.BusinessRequirements)
     {
       BusinessRequirement nbr = DataLayer.Get<BusinessRequirement>(s=>s.Id=br.Id).SingleOrDefault();
        if(nbr!=null)
          target.BusinessRequirements.Add(nbr);
     }  


     //3.
     //target.BusinessRequirements = source.BusinessRequirements;

     //4.
     //target.BusinessRequirements = new List<BusinessRequirement>();
     //foreach(BusinessRequirement br in source.BusinessRequirements)
     //{
     //  BusinessRequirement nbr = br;
     //   if(nbr!=null)
     //     target.BusinessRequirements.Add(nbr);
     //}  

      return target;
}

这四种方法都不能正常工作。

最接近工作的是2,但是发生了一件奇怪的事情。现在,如果我将任何 BusinessRequirements 添加到Original Project,它也会被添加到Clonned One,反之亦然,删除也是如此。

不知何故,实体框架将这两个项目视为一个项目。虽然这种行为只发生在多对多相关的导航属性中。

为什么 EntityFramework 的行为是这样的???。我错过了什么?请帮忙..

它已经快一天了,但我无法让它工作。

我试过这个这个这个这个,但他们也没有工作..

4

2 回答 2

2

您可以使用将对象添加到上下文将其对象图中任何子对象的状态更改为Added

Project proj;
using (var db = new MyDbContext())
{
    // Fetch a detached project and populate its BusinessRequirements.
    proj = db.Projects.AsNoTracking().Include(p => p.BusinessRequirements)
             .First(p => p.Id == source.Id);
    db.Projects.Add(proj);
    db.SaveChanges();
}

通过使用AsNoTracking上下文获取源项目不会将其添加到其更改跟踪器中,并且下一行将db.Projects.Add(proj);项目及其附属子对象视为全新的。

默默地,我放弃了你在一个静态上下文中工作的策略。这是一个不同的话题,但你不应该那样做。上下文应该有很短的生命周期。

于 2013-02-10T15:45:50.570 回答
0

由于您复制 BusinessRequirement 的方式而存在问题。您只是将引用从源添加到目标。因此,每个 BusinessRequirement 最终都会引用两个项目。

你需要做这样的事情。

    target.BusinessRequirements = new List<BusinessRequirement>();
         foreach(BusinessRequirement br in source.BusinessRequirements)
         {
           BusinessRequirement obr = DataLayer.Get<BusinessRequirement>(s=>s.Id=br.Id).SingleOrDefault();
BusinessRequirement obr = new BuisnessRequirment();
            if(nbr!=null){
//copy protperies in obr to nbr
}
              target.BusinessRequirements.Add(nbr);
         }  
于 2013-02-09T16:56:29.433 回答