多对多链接表实体框架插入

时间:2017-07-13 12:43:25

标签: c# sql sql-server entity-framework linktable

我有以下关系: Tables relationship

以下类(仅限相关属性):

  1. 事件:( AffairID,Title,...,AffairsGroups)
  2. 组:(GroupID,Name,...,AffairsGroups)
  3. 事务组(AffairID,GroupID,事务,组)
  4. 我想在数据库中添加一条新的Affair记录,该记录也将被添加到IncidentGroups表中(使用已知的GroupID)我已经尝试过以下方式:

    private Boolean addAffairToDatabase(Affair affair)
        {
            AffairDal affairContext = new AffairDal();
            affairContext.Affairs.Add(affair);
            affairContext.SaveChanges();
    
            AffairsGroupDal affairsGroupContext = new AffairsGroupDal();
            affairsGroupContext.AffairsGroups.Add(new AffairsGroup{ AffairID = affair.AffairID , GroupID = user.GroupID});
            affairsGroupContext.SaveChanges();
            return true;
        }
    

    但我得到以下例外:

    SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.AffairsGroups_dbo.Affairs_AffairID". The conflict occurred in database "NuixTest.DAL.AffairsGroupDal", table "dbo.Affairs", column 'AffairID'.
    

    这些是我的上下文类: 1。

    public class AffairDal: DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Affair>().ToTable("Affairs");
        }
        public DbSet<Affair> Affairs { get; set; }
    }
    

    2

    public class AffairsGroupDal: DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<AffairsGroup>().ToTable("AffairsGroups");
        }
        public DbSet<AffairsGroup> AffairsGroups { get; set; }
    }
    

    我做错了什么? 感谢

1 个答案:

答案 0 :(得分:0)

如果您的AffairsGroups位于同一个数据库中,则应将其DbSet放在同一个DbContext中。

此外,遵循Entity Framework Code First Conventions是一种好习惯。这样就不需要添加各种属性或Fluent API

您的AffairsGroups有一个相当简单的多对多关系:Group有零个或多个Affairs,每个Affair都可以成为零或多于Groups的成员。

请参阅Configure Many-to-Many

class Affair
{
    public int Id {set; set;}

    // an Affair can be member of many Groups:
    public virtual ICollection<Group> Groups {get; set;}
    ... 
}

classs Group
{
    public int Id {set; set;}

    // a Group can have many Affairs:
    public virtual ICollection<Affair> Affairs {get; set;}
    ... 
}

class MyDbContext : DbContext
{
    public DbSet<Affair> Affairs {get; set;}
    public DbSet<Group> Groups {get; set;}
}

实体框架将使用表名称事务和组,如果您确实要将它们命名为AffairGroup而没有终止,请考虑使用流畅的API。

实体框架会自动检测多对多关系并创建第三个表(AffairsGroups),如果您不喜欢默认名称,请再次使用流畅的API。

好处是,在你对多对多的正常处理中,你不需要第三个表。选择一个事件并将组添加到它,或选择一个组并将事件添加到它。

using (var myDbContext = ...)
{
    // add an affair that is not in a Group yet:
    var affair1 = myDbContext.Affairs.Add(new Affair()
    {
        Groups = new List<Group>(); // not in any group yet
    });

    // add a Group that has affair1 in it:
    var group1 = myDbContext.Groups.Add(new Group()
    {
        Affairs = new List<Affair>()
        {   // only one member: affair1:
            affair1,
        },
    });
    MyDbContext.SaveChanges();

    // as a test: retrieve affair1 again and see that it suddenly has a Group in it:
    var retrievedAffair = myDbContext.Affairs
        .Where(affair => affair.Id == affair1.Id)
        .Single();
     Debug.Assert(retrievedAffair.Groups.Any());
     Group groupOfAffair = retrievedAffair.Groups.First();
     Debug.Assert(groupOfAffair.Id == group1.Id);
}

因此,如果不使用事件组表,您可以添加包含或不包含组的事件,或者包含或不包含事务的组。您不需要使用此表的中间表或连接。

// get all Affairs that are in a Group with Name:
IEnumerable<Affair> affairs = myDbContext.Groups
    .Where(group => group.Name == Name)
    .Select(group => group.Affairs);