2017-09-01 105 views
0

我有很多在我的模型很多關係:多對多關係插入不正確

Tag.cs​​

public class Tag 
{ 
    // more properites ... 

    // user relations with forgin key 
    public User CreatedBy { get; set; } 
    public Guid CreatedById { get; set; } 

    // has many posts 
    public ICollection<Post> Posts { get; set; } 
} 

這裏是標籤Canfiguration:

HasRequired(o => o.CreatedBy) 
      .WithMany(user => user.Tags) 
      .HasForeignKey(tag => tag.CreatedById) 
      .WillCascadeOnDelete(false); 

Post.cs

public class Post 
{ 
    public ICollocation<Tag> Tag { get; set; } 
} 

及配置:

HasMany(post => post.Tags) 
      .WithMany(tag => tag.Posts) 
      .MapToStoredProcedures(); 

這裏是我插入後有多個標籤插入操作代碼:

public async Task InsertAsync(CreatePost postDto) 
    { 
     using (var transaction = _uow.Database.BeginTransaction()) 
     { 
      // map dto class to Post 
      var post = _mapper.Map<Post>(postDto); 

      // here split tag names in dto 
      var postTgs = postDto.TagNames.Split(','); 

      // i get tags that contains postTags names 
      var tags = await _tags.AsNoTracking().Where(x => postTgs.Contains(x.Name)).ToListAsync().ConfigureAwait(false); 

      _posts.Add(post); 

      await _uow.SaveAllChangesAsync().ConfigureAwait(false); 

      // get added post for add tags 
      var newPost = await _posts.Include(o => o.Tags).SingleAsync(x => x.Id == post.Id).ConfigureAwait(false); 

      foreach (var tag in tags) 
      { 
       // here add tags 
       newPost.Tags.Add(new Tag(){Name = tag.Name,CreatedById = tag.CreatedById}); 
      } 

      await _uow.SaveAllChangesAsync().ConfigureAwait(false); 
      transaction.Commit(); 
     } 
    } 

問題是,它在數據庫中插入多個標籤插入柱標籤。這opration添加新標籤標籤表但我想添加存在標籤PostTags Ef生成它Automaticaly。

  1. 我該如何解決這個問題?
  2. 爲什麼此操作插入新標籤?

我解決這個問題看其他文件和問題,但沒有得到result.I認爲我必須在我的模型來解決這一創造PostTags

注:標記與用戶有外鍵。

回答

2

爲什麼此操作插入新標籤?

因爲您正在添加使用new Tag { ... }創建的Tag實例。由於它們不屬於DbContext,因此EF假定它們是新記錄(不僅僅是指向現有記錄的新鏈接)。

我該如何解決這個問題?

確保Tag實例已正確連接到DbContext,並且狀態指示了現有記錄。

它並不完全來自你的代碼清晰,但如果_posts_tags從由_uow使用的相同DbContextDbSet S,所有你需要的是得到一個包含postTags名稱標籤時,從而使正確的追蹤他們刪除AsNoTracking因爲現有的,然後只需添加後的背景下,這樣告訴EF添加鏈接之前分配該列表作爲後標籤:

var post.Tags = await _tags.Where(x => postTgs.Contains(x.Name)).ToListAsync().ConfigureAwait(false); 

_posts.Add(post); 

await _uow.SaveAllChangesAsync().ConfigureAwait(false); 

transaction.Commit(); 

注意交易是在這種情況下,多餘的,因爲SaveChanges已經不適合您。