实体框架:重复的记录中的许多一对多的关系实体、框架、关系

2023-09-02 21:37:04 作者:爱到深处变成瘾❀

我有以下实体框架code首先code。创建表和数据插入。然而,有在俱乐部表中重复的记录。

我的操作是: -

创建使用俱乐部创建的应用程序会

创建一个使用个人应用程序的人

如何避免重复条目?

 静态无效的主要(字串[] args)
    {
        Database.SetInitializer&其中; NerdDinners>(新MyInitializer());

        CreateClubs();
        InsertPersons();

    }

    公共静态无效CreateClubs()
    {

        字符串的ConnectionString =数据源=;初始目录= NerdDinners;集成安全性= TRUE;连接超时= 30;
        使用(VAR DB =新NerdDinners(的ConnectionString))
        {

            俱乐部club1 =新东家();
            club1.ClubName =club1;

            俱乐部club2 =新东家();
            club2.ClubName =club2;

            俱乐部club3 =新东家();
            club3.ClubName =club3;

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

            INT recordsAffected = db.SaveChanges();


        }
    }

    公共静态俱乐部GetClubs(字符串clubName)
    {
        字符串的ConnectionString =数据源=;初始目录= NerdDinners;集成安全性= TRUE;连接超时= 30;
        使用(VAR DB =新NerdDinners(的ConnectionString))
        {

            // VAR的查询= db.Clubs.Where(P => p.ClubName == clubName);
            VAR的查询= db.Clubs.SingleOrDefault(P => p.ClubName == clubName);
            返回查询;
        }
    }

    公共静态无效InsertPersons()
    {
        字符串的ConnectionString =数据源=;初始目录= NerdDinners;集成安全性= TRUE;连接超时= 30;
        使用(VAR DB =新NerdDinners(的ConnectionString))
        {

            俱乐部club1 = GetClubs(club1);
            俱乐部club2 = GetClubs(club2);
            俱乐部club3 = GetClubs(club3);

            人P1 =新的Person();
            p1.PersonName =PERSON1;

            人P2 =新的Person();
            p2.PersonName =PERSON2;

            名单<俱乐部GT; clubsForPerson1 =新的名单,其中,俱乐部>();
            clubsForPerson1.Add(club1);
            clubsForPerson1.Add(club3);

            名单<俱乐部GT; clubsForPerson2 =新的名单,其中,俱乐部>();
            clubsForPerson2.Add(club2);
            clubsForPerson2.Add(club3);

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

            db.Persons.Add(p1)为;
            db.Persons.Add(P2);

            INT recordsAffected = db.SaveChanges();


        }
    }
 

 公共类Person
{
    公众诠释PERSONID {获得;组; }
    公共字符串PersonName的{获得;组; }
    公共虚拟的ICollection<俱乐部GT;俱乐部{获得;组; }
}

公共类俱乐部
{
    公众诠释ClubId {获得;组; }
    公共字符串ClubName {获得;组; }
    公共虚拟的ICollection<人>成员{获得;组; }
}

//System.Data.Entity.DbContext是EntityFramework.dll
公共类NerdDinners:System.Data.Entity.DbContext
{

    公共NerdDinners(字符串CONNSTRING):基地(CONNSTRING)
    {

    }

    保护覆盖无效OnModelCreating(DbModelBuilder模型构建器)
    {
         //流利的API  - 复数去除
        modelbuilder.Conventions.Remove&其中; PluralizingTableNameConvention>();
    }

    公共DbSet<人>人{获得;组; }
    公共DbSet<俱乐部GT;俱乐部{获得;组; }

}
 
Spring Batch批处理框架,真心强啊

解决方案

现在的问题是,你创造更多的上下文。

首先创建的俱乐部。好的。但是当你创建者,您将获取通过 GetClubs 的俱乐部,但对于每一个俱乐部,你处理的实际实体框架范围内,所以你最终获得独立的实体。在 InsertPersons 你加分离的俱乐部实体到新的人,因此实际情况下会认为俱乐部新的俱乐部。

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

这是因为实体框架跟踪变化和管理每个对象的实体。如果添加一个实体上下文不包含现在还那么它会像对待一个新的实体。

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

 静态无效的主要(字串[] args)
{
    Database.SetInitializer&其中; NerdDinners>(新MyInitializer());

    字符串的ConnectionString =数据源=;初始目录= NerdDinners;集成安全性= TRUE;连接超时= 30;
    使用(VAR DB =新NerdDinners(的ConnectionString))
    {
        CreateClubs(DB);
        InsertPersons(DB);
    }

}

公共静态无效CreateClubs(NerdDinners DB)
{
    俱乐部club1 =新东家();
    club1.ClubName =club1;

    俱乐部club2 =新东家();
    club2.ClubName =club2;

    俱乐部club3 =新东家();
    club3.ClubName =club3;

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

    INT recordsAffected = db.SaveChanges();
}

公共静态俱乐部GetClubs(字符串clubName,NerdDinners DB)
{
    // VAR的查询= db.Clubs.Where(P => p.ClubName == clubName);
    VAR的查询= db.Clubs.SingleOrDefault(P => p.ClubName == clubName);
    返回查询;
}

公共静态无效InsertPersons(NerdDinners DB)
{
    俱乐部club1 = GetClubs(club1,分贝);
    俱乐部club2 = GetClubs(club2,分贝);
    俱乐部club3 = GetClubs(club3,分贝);

    人P1 =新的Person();
    p1.PersonName =PERSON1;

    人P2 =新的Person();
    p2.PersonName =PERSON2;

    名单<俱乐部GT; clubsForPerson1 =新的名单,其中,俱乐部>();
    clubsForPerson1.Add(club1);
    clubsForPerson1.Add(club3);

    名单<俱乐部GT; clubsForPerson2 =新的名单,其中,俱乐部>();
    clubsForPerson2.Add(club2);
    clubsForPerson2.Add(club3);

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

    db.Persons.Add(p1)为;
    db.Persons.Add(P2);

    INT recordsAffected = db.SaveChanges();
}
 

当然,你应该重构这个code中的结构,但请注意,我只用一个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:-

Create clubs using club creation app

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.