2

我還是首先在EF代碼中新建的,所以請對我寬大處理。多對多關係更新:無法插入複製密鑰

我有這些實體類:

public class User 
    { 
     public int UserId { get; set; } 
     public string UserName { get; set; } 
     public string EmailAddress { get; set; } 
     public string Password { get; set; } 
     public virtual ICollection<Task> Tasks { get; set; } 
     public virtual ICollection<Task> TaskAssignees { get; set; } 

     public User() 
     { 
      Tasks = new List<Task>(); 
     } 
    } 

    public class Task 
    { 
     public int TaskId { get; set; } 
     public string Name { get; set; } 
     public virtual User CreateBy { get; set; } 
     public int UserId { get; set; } 
     public virtual ICollection<User> Assignees { get; set; } 

     public Task() 
     { 
     Assignees = new List<User>(); 
     } 
    } 

與映射配置:

public class UserMap : EntityTypeConfiguration<User> 
{ 
    public UserMap() 
    { 
     Property(u=>u.UserName) 
      .IsRequired() 
      .HasMaxLength(30); 
     Property(u => u.EmailAddress) 
      .IsRequired() 
      .HasMaxLength(255); 
     Property(u => u.Password) 
      .IsRequired() 
      .HasMaxLength(255); 
    } 
} 

public class TaskMap : EntityTypeConfiguration<Domain.Entities.Task> 
{ 
    public TaskMap() 
    { 
     Property(t => t.Name) 
      .IsRequired() 
      .HasMaxLength(255); 
     HasRequired(t => t.CreateBy) 
      .WithMany(u => u.Tasks) 
      .HasForeignKey(t => t.UserId) 
      .WillCascadeOnDelete(false) 
      ; 
     HasMany(t => t.Assignees) 
      .WithMany(u => u.TaskAssignees) 
      .Map(a => 
       { 
        a.ToTable("TaskAssignees"); 
        a.MapLeftKey("TaskId"); 
        a.MapRightKey("UserId"); 
       }) 
      ; 
    } 
} 

和一個非常通用的庫類:

public class EntityRepository<TEntity> : IEntityRepositoryGetWithCRUD<TEntity> where TEntity : class 
    { 
     internal DbContext context; 
     internal DbSet<TEntity> dbSet; 

     public EntityRepository(DbContext Context) 
     { 
      this.context = Context; 
      this.dbSet = context.Set<TEntity>(); 
     } 

     public virtual IQueryable<TEntity> All 
     { 
      get { return dbSet; } 
     } 

     public virtual IQueryable<TEntity> AllIncluding(params System.Linq.Expressions.Expression<Func<TEntity, object>>[] IncludeProperties) 
     { 
      IQueryable<TEntity> query = dbSet; 

      foreach (var includeProperty in IncludeProperties) 
      { 
       query = query.Include(includeProperty); 
      } 
      return query; 
     } 

     public virtual IEnumerable<TEntity> Get(
      Expression<Func<TEntity, bool>> Filter = null, 
      Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> OrderBy = null, 
      params System.Linq.Expressions.Expression<Func<TEntity, object>>[] IncludeProperties) 
     { 
      IQueryable<TEntity> query = dbSet; 

      if (Filter != null) 
      { 
       query = query.Where(Filter); 
      } 

      foreach (var includeProperty in IncludeProperties) 
      { 
       query = query.Include(includeProperty); 
      } 

      if (OrderBy != null) 
      { 
       return OrderBy(query).ToList(); 
      } 
      else 
      { 
       return query.ToList(); 
      } 
     } 

     public virtual TEntity Find(int Id) 
     { 
      return dbSet.Find(Id); 
     } 

     public virtual void Insert(TEntity Entity) 
     { 
      dbSet.Add(Entity); 
     } 

     public virtual void Update(TEntity Entity) 
     { 
      dbSet.Add(Entity); 
      context.Entry(Entity).State = EntityState.Modified; 
     } 

     public virtual void Delete(int Id) 
     { 
      var entity = dbSet.Find(Id); 
      dbSet.Remove(entity); 
     } 

     public virtual void Delete(TEntity Entity) 
     { 
      if (context.Entry(Entity).State == EntityState.Detached) 
      { 
       dbSet.Attach(Entity); 
      } 
      dbSet.Remove(Entity); 

     } 

     public virtual void Dispose() 
     { 
      context.Dispose(); 
     } 

     public virtual void Save() 
     { 
      context.SaveChanges(); 
     } 

    } 

利用上述碼,我可以插入一個新的任務順利地進入db。 但是當我試圖用這個簡單的代碼來更新任務的問題就出來了:

Task task = repository.Find(2); 

if (task != null) 
{ 
    task.Name = "Test Update"; 
    repository.Update(task); 
    repository.Save(); 
} 

錯誤說:

違反PRIMARY KEY約束「PK_dbo.TaskAssignees」的。 不能在對象'dbo.TaskAssignees'中插入重複鍵。聲明已經終止 。

請問有人能給我一些啓發嗎?

回答

0

我認爲你的問題可能在於你如何調用更新。

我不確定,但我認爲你的實體已經被上下文管理,所以你不需要添加它來將它置於更新狀態。如果你只是刪除電話更新並嘗試保存,一切工作嗎?

+0

謝謝,這是解決我的問題......我跟着一些教程來創建通用的資源庫類,我想我沒有很好地遵循它。 –

+0

我的猜測是更新是將任務添加爲新對象,並嘗試在保留相關受託人時也將其保存爲新實體。儘管我在這方面的知識已經超出了我的範圍。 – Matthew