2016-04-14 8 views
1

GraphDiffを使用して、分離されたオブジェクトグラフを更新しました。1つまたは複数の外部キープロパティが保存時にNULLを許可されないため、関係を変更できませんでした

モデルとマッピングは、次のとおりです。

挿入および更新のために
public class Group 
{ 
    public int Id { get; set; } 
    public virtual ICollection<GroupUser> Users{ get; set; } 
} 

public class GroupUser 
{ 
    public int Id { get; set; } 
    public int GroupId { get; set; } 
    public int UserId { get; set; } 
    public virtual User User { get; set; } 
} 

public class GroupMap : EntityTypeConfiguration<Group> 
{ 
    public GroupMap() 
    { 
     this.ToTable("groups"); 
     this.HasKey(t => t.Id).Property(t => t.Id).HasColumnName("id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

     this.HasMany(t => t.Users) 
      .WithOptional() 
      .HasForeignKey(d => d.GroupId) 
      .WillCascadeOnDelete(); 
    } 
} 

public class GroupUserMap : EntityTypeConfiguration<GroupUser> 
{ 
    public GroupUserMap() 
    { 
     this.ToTable("groups_users"); 
     this.HasKey(t => t.Id).Property(t => t.Id).HasColumnName("id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     this.Property(t => t.GroupId).HasColumnName("group_id").IsRequired(); 
     this.Property(t => t.UserId).HasColumnName("user_id").IsRequired(); 

     this.HasRequired(t => t.User) 
      .WithMany() 
      .HasForeignKey(d => d.UserId) 
      .WillCascadeOnDelete(false); 
    } 
} 

私は自分のリポジトリにこの次のような方法があります。

public override Group Update(Group entity) 
{ 
    if (entity.Users != null) 
    { 
     entity.Users.ToList() 
        .ForEach(x => 
        { 
         x.GroupId = x.Id == 0 ? 0 : entity.Id; 
         x.UserId = x.User.Id; 
        }); 
    } 

    return dbContext.UpdateGraph<Group> 
     (entity, 
      map => map.OwnedCollection(x => x.Users, with => with.AssociatedEntity(c => c.Users)) 
     ); 
} 

を私は次の操作を行います

  1. 追加新しいグループ、保存、再読み込み
  2. ユーザーをグループに追加して保存し直してください負荷
  3. 、第二のユーザを追加し、保存し、リロード
  4. 保存しようと、第3のユーザの追加 - >例外はデバッグなくなり

をスローされ、追加されたユーザエンティティの状態は常に取り外し、 GroupIdIdの両方が新しいエンティティに対して0に設定されています。追加された最初の2人のユーザーは正常に保存されます。ただし、3番目の例外では、例外がスローされます。

私はいつも同じ方法で保存していますが、それはいつもうまくいかないのですか? EFまたはGraphDiffの問題ですか?この問題を解決する方法はありますか?

ここでのほとんどの質問とその回答は、子エンティティが削除されている状況をすべて扱います。これは私の特定のシナリオでは当てはまりません。

答えて

0

はおそらくNULL可能でないUSERIDに関連しているがthis.itがテストされてみてください。ご存じのように、UserIdはEFによってUserの作成に使用されます。 Userがnullの場合、EFはエンティティを書き込めません。 また、Group.UsersコレクションをマップするためにEFによって使用されるUser.GroupIdに関連する可能性があります。

また、あなたのモデルを理解できません。 ユーザーには1つのグループしかありません。 グループは複数のユーザーを持つことができます。

これが当てはまる場合、アソシエーションエンティティを削除するだけでモデルを単純化するのはなぜですか? EFはそれを必要としません...

public class Group 
{ 
    public int Id { get; set; } 
    public virtual ICollection<User> Users{ get; set; } 
} 

public class User 
{ 
    public int Id { get; set; } 
    public virtual Group Group { get; set; } 
} 

この場合、あなただけのUserMapが必要です。

public class UserMap : EntityTypeConfiguration<User> 
{ 
    public UserMap() 
    { 
     // You don't need to set primary key. EF take Id and create an identity column 
     //HasKey(t => t.Id); 

     // Table & Column Mappings 
     ToTable("users"); 
     // No column mappings in this case. 

     // Relationships 
     HasRequired(t => t.Group) 
      .WithMany(t => t.Users) 
      .Map(d => d.MapKey("user_group")); 

    } 
} 

ユーザーは、EFは、それが多くの関係に多くのです理解し

public class User 
{ 
    public int Id { get; set; } 
    public virtual ICollection<Group> Groups { get; set; } 
} 

あなたはこの方法であなたのユーザモデルを変更することができ、複数のグループは、関連テーブル(UsersGroupsを作成することができた場合)しかし、関連エンティティは必要ありません。あなたはEF6でdb.Entry(myEntity).State = EntityState.Modified;を設定する必要が

EDITまれ

。プロキシーはかなりうまく動作します。

1

エンティティの状態がEFによって追跡されていないときに変更されているかどうか試しましたか?

は、ToListメソッド()関数はまた、あなたが誤ってユーザーの状態を変更させることができ

db.Entry(currentUser).State = EntityState.Modified; 
を試してみてください。

+0

'ToList()'を通常の 'foreach'に変更しても違いはありません。 –

+0

「状態」が正しく追加されました。 –

+0

「状態」が追加され、変更されていない場合、エンティティの切断に関する問題のように聞こえます。私の推測では、EFは 'GroupUser'を再作成して、保存しようとすると以前の 'GroupUser'をnullにしています。以前に追加したユーザーの値を印刷しましたか? – kermitvomit

0

public override Group Update(Group entity) 
{ 
    if (entity.Users != null) 
    { 
     foreach(var user in entity.Users){ 
      user.GroupId = x.Id == 0 ? 0 : entity.Id; 
      user.UserId = x.User.Id; 
     dbContext.Entry(child).State = EntityState.Modified; 
     } 

    } 

    return dbContext.UpdateGraph<Group> 
     (entity, 
      map => map.OwnedCollection(x => x.Users, with => with.AssociatedEntity(c => c.Users)) 
     ); 
} 
関連する問題