实体框架:多对多关系中的重复记录 [英] Entity Framework: Duplicate Records in Many-to-Many relationship

查看:116
本文介绍了实体框架:多对多关系中的重复记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下实体框架代码第一个代码。创建表并插入数据。但是在俱乐部表中有重复的记录。



我的操作是: -


  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;
使用(var db = new NerdDinners(connectionstring))
{

俱乐部club1 = new Club();
club1.ClubName =club1;

俱乐部俱乐部2 =新俱乐部();
club2.ClubName =club2;

俱乐部俱乐部3 =新俱乐部();
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 = 。;初始目录= NerdDinners;集成安全= True;连接超时= 30;
使用(var db = new NerdDinners(connectionstring))
{

// var query = db.Clubs.Where(p => p.ClubName == clubName) ;
var query = db.Clubs.SingleOrDefault(p => p.ClubName == clubName);
返回查询;
}
}

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

俱乐部俱乐部1 = GetClubs(club1);
俱乐部俱乐部2 = GetClubs(club2);
俱乐部俱乐部3 = GetClubs(club3);

个人p1 = new Person();
p1.PersonName =Person1;

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

列表<俱乐部> clubsForPerson1 =新列表< Club>();
clubsForPerson1.Add(club1);
clubsForPerson1.Add(club3);

列表<俱乐部> 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();


}
}

p>

  public class Person 
{
public int PersonId {get;组; }
public string PersonName {get;组; }
public virtual ICollection< Club>俱乐部{get;组; }
}

public class Club
{
public int ClubId {get;组; }
public string ClubName {get;组; }
public virtual ICollection< Person>会员{get;组; }
}

//System.Data.Entity.DbContext来自EntityFramework.dll
public class NerdDinners:System.Data.Entity.DbContext
{

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

}

protected override void OnModelCreating(DbModelBuilder modelbuilder)
{
//流利的API - 多重删除
modelbuilder.Conventions.Remove< PluralizingTableNameConvention>();
}

public DbSet< Person>人{get;组; }
public DbSet< Club>俱乐部{get;组;

}


解决方案

问题是您创建更多的上下文。



首先创建俱乐部。没关系。但是,当您创建人员时,您可以通过 GetClubs 获取俱乐部,但是对于每个俱乐部,您将处理实际的实体框架上下文,以便最终获得分离的实体。在 InsertPersons 中,您将独立的俱乐部实体添加到新人员,因此实际上下文会认为俱乐部是新俱乐部。



所以当你为一个人添加一个俱乐部,你实际上创建了新的俱乐部。



这是因为实体框架跟踪变化并管理每个上下文的实体。如果您将一个实体添加到不包含它的上下文中,那么它将像一个新实体一样对待。



其实你应该这样做(未测试) :

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

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

}

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

俱乐部俱乐部2 =新俱乐部();
club2.ClubName =club2;

俱乐部俱乐部3 =新俱乐部();
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);
返回查询;
}

public static void InsertPersons(NerdDinners db)
{
俱乐部俱乐部1 = GetClubs(club1,db);
俱乐部俱乐部2 = GetClubs(club2,db);
俱乐部俱乐部3 = GetClubs(club3,db);

个人p1 = new Person();
p1.PersonName =Person1;

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

列表<俱乐部> clubsForPerson1 =新列表< Club>();
clubsForPerson1.Add(club1);
clubsForPerson1.Add(club3);

列表<俱乐部> 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上下文进行操作。


I have following entity framework code first code. The tables are created and data is inserted. However there are duplicate records in Club table.

My operations are:-

  1. Create clubs using club creation app

  2. Create persons using person app

How to avoid the duplicate entry?

    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();


        }
    }

Domain

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

}

解决方案

The problem is that you create more contexts.

First you create the clubs. It's ok. But when you create the persons, you fetch the clubs via GetClubs, but for each club you dispose the actual entity framework context so you end up with detached entities. At InsertPersons you add detached club entities to the new persons so the actual context will think that the clubs are new clubs.

So when you add a club to a person you actually create new clubs.

This is because entity framework tracks the changes and manages the entities per context. If you add an entity to a context which does not contains it yet then it will treat like a new entity.

Actually, you should do something like this (not tested):

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

Of course you should refactor the structure of this code, but please notice that I use only one EF context for my operations.

这篇关于实体框架:多对多关系中的重复记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆