【问题标题】:MTM relationship in EF CodeFirst - updating woesEF CodeFirst 中的 MTM 关系 - 更新问题
【发布时间】:2015-10-18 10:55:56
【问题描述】:

我遇到了 Entity Framework 6.1.3 CodeFirst 多对多关系的问题。我的模型基本上是这样的:

class Schedule
{
    int Id { get; set; }
}

class Contest
{
    int Id { get; set; }

    ICollection<Schedule> GameSchedules { get; set; }
}

我的上下文供参考:

class MyContext
{
    MyContext() : base("name=DefaultConnection")
    {
        // no lazy loading for us
        this.Configuration.LazyLoadingEnabled = false;

        // do not auto detect changes for me
        this.Configuration.AutoDetectChangesEnabled = false;

        // we don't want our stuff to be wrapped in proxies 
        this.Configuration.ProxyCreationEnabled = false;
    }
}

Entity Farmework CodeFirst 配置:

class ContestConfiguration : EntityTypeConfiguration<Contest>
{
    ContestConfiguration()
    {
        // setup many-to-many table between game schedules and contests
        this.HasMany(contest => contest.GameSchedules)
            .WithMany(schedule => schedule.Contests)
            .Map(
                contestSchedule =>
                {
                    contestSchedule.MapLeftKey("ContestId");
                    contestSchedule.MapRightKey("ScheduleId");
                    contestSchedule.ToTable("ContestSchedule", "something");
                });
    }
}

在使用现有时间表创建比赛时,我执行以下操作,我看到输入了两条 sql 语句,一条用于创建比赛,一条用于为 MTM 表创建记录。

Contest Add(Contest entity)
{
    // setup schedules
    entity.GameSchedules.ToList().ForEach(schedule => this.Context.Entry(schedule).State = EntityState.Unchanged);

    // call base add method
    return base.Add(entity);
}

然而,当我尝试更新时,情况就完全不同了。我尝试了很多方法,但无法让 CodeFirst 更新 MTM 表中的关系。它要么尝试删除计划以及 MTM 记录,要么什么都不做。关于如何完成这个令人兴奋的壮举有什么想法吗?

【问题讨论】:

    标签: entity-framework ef-code-first many-to-many


    【解决方案1】:

    好的,想通了。首先,从 MTM 表中删除每个 DELETE 上的 ManyToManyCascadeDeleteConvention 或其他,它也会尝试删除时间表或比赛。这是因为默认情况下 EntityFramework 将级联删除设置为 true。

    // remove many-to-many cascade auto delete
    modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
    

    现在这里是更新的代码 1. 确保您已将新计划复制到新集合 2. 用新数据修改现有实体(这可以在更新 MTM 表之前或之后完成) 3. 为简单起见,我只是从 MTM 表中删除了与此链接的所有当前行,并为简洁起见添加了新行。 4. 保存更改以确保删除计划 5.现在添加新的 6. 再次保存您的更改以确保添加了新的时间表

    public void Update(Contest entity)
    {
        // (1) generate new collection so that the reference doesn't get overwritten
        var schedulesToAdd = entity.GameSchedules.ToList();
    
        // (2) get entry
        var entry = this.context.Entry(entity);
    
        // set entry to modified
        entry.State = EntityState.Modified;
    
        // save the current state
        this.Context.SaveChanges();
    
        // get the existing context from the db
        var existingContest = this.Set.Where(contest => contest.Id == entity.Id).Include(contest => contest.GameSchedules).SingleOrDefault();
    
        // get the object context
        var context = ((IObjectContextAdapter)this.Context).ObjectContext;
    
        // iterate over existing relationships and eliminate
        foreach (var existingSchedule in existingContest.GameSchedules.ToList())
        {
            var schedule = this.Context.Schedules.Find(existingSchedule.Id);
    
            // (3) mark relationship as deleted
            context.ObjectStateManager.ChangeRelationshipState(existingContest, schedule, contest => contest.GameSchedules, EntityState.Deleted);
        }
    
        // (4) save the current state
        result = this.SaveChanges();
    
        // iterate over new entity relationships and add them
        foreach (var newSchedule in schedulesToAdd)
        {
            // find the schedule
            var schedule = this.Context.Schedules.Find(newSchedule.Id);
    
            // (5) mark relationship as added
            context.ObjectStateManager.ChangeRelationshipState(existingContest, schedule, contest => contest.GameSchedules, EntityState.Added);
        }
    
        // (6) save the current state
        this.SaveChanges();
    }
    

    请记住,您需要提出一些更精细的行为来删除现有关系并添加新关系。这只是一个例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 1970-01-01
      • 2019-11-19
      • 1970-01-01
      • 1970-01-01
      • 2021-07-04
      • 1970-01-01
      相关资源
      最近更新 更多