11

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

我的操作是:-

  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 上下文。

于 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() 实体框架 4.1 的问题
  2. 实体框架更新多对多关系 - POCO

于 2012-07-26T05:20:38.540 回答