11

私は次のエンティティフレームワークコードの最初のコードを持っています。テーブルが作成され、データが挿入されます。ただし、クラブテーブルに重複するレコードがあります。

私の操作は:-

  1. クラブ作成アプリを使用してクラブを作成する

  2. 人物アプリを使用して人物を作成する

重複エントリを回避する方法は?

ここに画像の説明を入力してください

    static void Main(string[] args)
    {
        Database.SetInitializer<NerdDinners>(new MyInitializer());

        CreateClubs();
        InsertPersons();

    }

    public static void CreateClubs()
    {

        string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30";
        using (var db = new NerdDinners(connectionstring))
        {

            Club club1 = new Club();
            club1.ClubName = "club1";

            Club club2 = new Club();
            club2.ClubName = "club2";

            Club club3 = new Club();
            club3.ClubName = "club3";

            db.Clubs.Add(club1);
            db.Clubs.Add(club2);
            db.Clubs.Add(club3);

            int recordsAffected = db.SaveChanges();


        }
    }

    public static Club GetClubs(string clubName)
    {
        string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30";
        using (var db = new NerdDinners(connectionstring))
        {

            //var query = db.Clubs.Where(p => p.ClubName == clubName);
            var query = db.Clubs.SingleOrDefault(p => p.ClubName == clubName);
            return query;
        }
    }

    public static void InsertPersons()
    {
        string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30";
        using (var db = new NerdDinners(connectionstring))
        {

            Club club1 = GetClubs("club1");
            Club club2 = GetClubs("club2");
            Club club3 = GetClubs("club3");

            Person p1 = new Person();
            p1.PersonName = "Person1";

            Person p2 = new Person();
            p2.PersonName = "Person2";

            List<Club> clubsForPerson1 = new List<Club>();
            clubsForPerson1.Add(club1);
            clubsForPerson1.Add(club3);

            List<Club> clubsForPerson2 = new List<Club>();
            clubsForPerson2.Add(club2);
            clubsForPerson2.Add(club3);

            p1.Clubs = clubsForPerson1;
            p2.Clubs = clubsForPerson2;

            db.Persons.Add(p1);
            db.Persons.Add(p2);

            int recordsAffected = db.SaveChanges();


        }
    }

ドメイン

public class Person
{
    public int PersonId { get; set; }
    public string PersonName { get; set; }
    public virtual ICollection<Club> Clubs { get; set; }
}

public class Club
{
    public int ClubId { get; set; }
    public string ClubName { get; set; }
    public virtual ICollection<Person> Members { get; set; }
}

//System.Data.Entity.DbContext is from EntityFramework.dll
public class NerdDinners : System.Data.Entity.DbContext
{

    public NerdDinners(string connString): base(connString)
    { 

    }

    protected override void OnModelCreating(DbModelBuilder modelbuilder)
    {
         //Fluent API - Plural Removal
        modelbuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }

    public DbSet<Person> Persons { get; set; }
    public DbSet<Club> Clubs { get; set; }

}
4

2 に答える 2

20

問題は、より多くのコンテキストを作成することです。

まず、クラブを作成します。大丈夫です。ただし、個人を作成するときは、 を介してクラブをフェッチしますが、クラブGetClubsごとに実際のエンティティ フレームワーク コンテキストを破棄するため、切り離されたエンティティになります。切り離されたクラブ エンティティを新しい人物にInsertPersons追加すると、実際のコンテキストではクラブが新しい​​クラブであると見なされます。

したがって、人にクラブを追加すると、実際には新しいクラブが作成されます。

これは、エンティティ フレームワークが変更を追跡し、コンテキストごとにエンティティを管理するためです。エンティティをまだ含んでいないコンテキストにエンティティを追加すると、新しいエンティティのように扱われます。

実際には、次のようにする必要があります (テストされていません)。

static void Main(string[] args)
{
    Database.SetInitializer<NerdDinners>(new MyInitializer());

    string connectionstring = "Data Source=.;Initial Catalog=NerdDinners;Integrated Security=True;Connect Timeout=30";
    using (var db = new NerdDinners(connectionstring))
    {
        CreateClubs(db);
        InsertPersons(db);
    }

}

public static void CreateClubs(NerdDinners db)
{
    Club club1 = new Club();
    club1.ClubName = "club1";

    Club club2 = new Club();
    club2.ClubName = "club2";

    Club club3 = new Club();
    club3.ClubName = "club3";

    db.Clubs.Add(club1);
    db.Clubs.Add(club2);
    db.Clubs.Add(club3);

    int recordsAffected = db.SaveChanges();
}

public static Club GetClubs(string clubName, NerdDinners db)
{
    //var query = db.Clubs.Where(p => p.ClubName == clubName);
    var query = db.Clubs.SingleOrDefault(p => p.ClubName == clubName);
    return query;
}

public static void InsertPersons(NerdDinners db)
{
    Club club1 = GetClubs("club1", db);
    Club club2 = GetClubs("club2", db);
    Club club3 = GetClubs("club3", db);

    Person p1 = new Person();
    p1.PersonName = "Person1";

    Person p2 = new Person();
    p2.PersonName = "Person2";

    List<Club> clubsForPerson1 = new List<Club>();
    clubsForPerson1.Add(club1);
    clubsForPerson1.Add(club3);

    List<Club> clubsForPerson2 = new List<Club>();
    clubsForPerson2.Add(club2);
    clubsForPerson2.Add(club3);

    p1.Clubs = clubsForPerson1;
    p2.Clubs = clubsForPerson2;

    db.Persons.Add(p1);
    db.Persons.Add(p2);

    int recordsAffected = db.SaveChanges();
}

もちろん、このコードの構造をリファクタリングする必要がありますが、操作に使用する EF コンテキストは 1 つだけであることに注意してください。

于 2012-07-25T09:54:05.080 に答える
0

@PeterPorfyに感謝

タイプ「System.ObjectDisposedException」の例外もお読みください

使った

 ((IObjectContextAdapter)db).ObjectContext.Attach((IEntityWithKey)entity); 

以前のコンテキストからオブジェクトを添付するため。

私が使用した IEntityWithKey の一例は次のとおりです。このアプローチに問題がある場合は、コメントしてください。

public class Person : IEntityWithKey
{
    public int PersonId { get; set; }
    public string PersonName { get; set; }

    public EntityKey EntityKey { get; set; }
}

以下も参考にしてください

  1. SaveChanges() Entity Framework 4.1 の問題
  2. 多対多のリレーションシップを更新するエンティティ フレームワーク - POCO

于 2012-07-26T05:20:38.540 に答える