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

そのため、どこかで多対多の関係を b/wProjectで構成し、次のBusinessRequirementようにしました。

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

Project今、私がしているのは、 ieのオブジェクトのコピーを作成しようとすることだけです

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

4 つの方法はどれも適切に機能しません。

動作に最も近いのは 2 ですが、奇妙なことが起こります。ここで、BusinessRequirements をOriginal Projectに追加すると、 にも追加さClonned Oneれます。逆もまた同様で、削除も同様です。

どういうわけか、entityframework は両方のプロジェクトを 1 つとして扱っています。ただし、この動作は多対多の関連するナビゲーション プロパティでのみ発生します。

なぜEntityFrameworkはこのように振る舞うのですか???. 私は何が欠けていますか?助けてください..

ほぼ1日が経ちましたが、うまくいきません。

thisthisthisthisを試しましたが、どちらも機能しませんでした..

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);でプロジェクトとそれに付随する子オブジェクトがまったく新しいものと見なされます。

静かに、私は 1 つの静的なコンテキストで動作するというあなたの戦略を放棄しました。それは別のトピックですが、それを行うべきではありません。コンテキストの寿命は短いはずです。

于 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 に答える