2016-08-07 224 views
0

我正在使用實體框架(6.1.3)和代碼優先方法。我有一個模型類電影和模型類標籤看起來像這樣:多對多關係 - 實體框架正在創建新對象

public class Movie 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public ICollection<Tag> Tags { get; set; } 
} 

public class Tag 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

在的DbContext我改寫OnModelCreating方法來建立這樣一個一對多的關係:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Movie>() 
       .HasMany(a => a.Tags) 
       .WithMany() 
       .Map(x => 
       { 
        x.MapLeftKey("Movie_Id"); 
        x.MapRightKey("Tag_Id"); 
        x.ToTable("MovieTags"); 
       }); 

    base.OnModelCreating(modelBuilder); 
} 

如果我嘗試使用某些標籤將影片插入數據庫,我遇到了創建不需要的標籤的問題。

例如,我已經在數據庫中有兩個標籤「Foo」(Id:1)和「Bar」(Id:2)。現在我創建一個新的Movie對象,並將現有標籤「Foo」(從數據庫加載)和新標籤「Foobar」插入到對象的集合中。將此影片添加到DbContext並調用方法「SaveChanges」後,我的數據庫中有兩個新標籤。

爲什麼實體框架爲我的數據庫插入一個存在的標籤?我必須改變什麼,只有缺失的標籤被插入?

編輯-1: 這裏是控制器代碼,我添加了標籤,並將其保存

List<Tag> tagList = new List<Tag>(); 
// ViewModel.Tags either contains the Tag-Id or the Tag-Name (if it is new) 
foreach (string tag in viewModel.Tags) 
{ 
    if (IsDigitsOnly(tag)) 
    { 
     // Load the existing Tag from the DbContext and add to List 
     tagList.Add(TagService.Get(int.Parse(tag))); 
    } 
    else 
    { 
     // Create new Tag 
     tagList.Add(new Tag() { Name = tag }); 
    } 
} 

Movie movie = new Movie(); 
movie.Name = viewModel.Name; 
movie.Tags = tagList; 

MovieService.Insert(movie); 

這裏是與刀片

public void Insert(Movie movie) 
{ 
    Context.Movie.Add(movie); 
    Context.SaveChanges(); 
} 

編輯-2 MovieService碼: 我發現問題了!這是我如何設置我的項目的一個問題。我使用Ninject進行DI,並且沒有將DbContext綁定到請求(InRequestScope)。所以每次我的一個服務被調用時,它都會使用不同的DbContext,因爲它不知道已經加載了標籤。

+0

你能否糾正帖子標題 - 你在做什麼是多對多的關係。 –

+0

是的,我改變了。我不知道我爲什麼寫「一對多」。我知道這是很多很多... – Shamshiel

回答

0

您可以提供代碼添加標籤的位置嗎?

在此期間,我以爲這是類似

Movie.Tags.Add(new Tag { Name = "foo" }); 

你可能會想,如下所示添加現有標籤:

Movie.Tags.Add(ctx.Tags.First(T => T.Name == "foo")); 

...或等效的代碼,將得到來自您的上下文的標籤。

此外,您可能希望使標籤ICollection虛擬,以便代理可以覆蓋它。這可能也是一個很難找到的錯誤來源。

+0

我編輯我的原始問題,我如何添加標籤。但是現在我發現了這個問題,我也將它添加到了我原來的問題中。 – Shamshiel

+0

太好了。祝你好運。 – DPH