2014-10-06 132 views
0

我遇到了實體框架的嚴重問題,我無法解決它。 我有2個實體,一個章節和一個標題,標題通過使用導航屬性鏈接到一個章節。實體框架:使用關係添加實體,創建新實體

[Table("T_CHAPTER")] 
public class Chapter : EntityBase<int> 
{ 
    [Required] 
    [Column(Order = 1)] 
    public string Name { get; set; } 
} 

[Table("T_HEADER")] 
public class Header : EntityBase<int> 
{ 
    [Required] 
    [Column(Order = 1)] 
    public string Name { get; set; } 

    [Required] 
    [Column(Order = 2)] 
    public virtual Chapter Chapter { get; set; } 
} 

到目前爲止,這裏沒有什麼特別的。 現在,我想告訴我,我正在使用工作單元和存儲庫模式,但我不認爲這是介意的。

首先,我將在各章增加一條記錄,如果不存在的話,那這個代碼實現:

private Chapter CreateChapter(string chapter) 
{ 
    var retrievedChapter = UnitOfWork.ChapterRepository.Get(x => x.Name.Equals(chapter, StringComparison.InvariantCultureIgnoreCase)); 

    if (retrievedChapter == null) 
    { 
     UnitOfWork.ChapterRepository.Insert(new Chapter { Name = chapter }); 
     UnitOfWork.Commit(); 

     retrievedChapter = UnitOfWork.ChapterRepository.Get(x => x.Name.Equals(chapter, StringComparison.InvariantCultureIgnoreCase)); 
    } 

    return retrievedChapter; 
} 

的插入方法如下:

public virtual void Insert(TEntity entity) 
{ 
    if (OnBeforeEntityInsert != null) 
    { OnBeforeEntityInsert(this, new RepositoryEventArgs(typeof(TEntity), entity)); } 

    DbSet.Add(entity); 

    if (OnEntityInsert != null) 
    { OnEntityInsert(this, new RepositoryEventArgs(typeof(TEntity), entity)); } 
} 

而這裏的Commit方法:

public void Commit() 
{ 
    if (OnBeforeCommit != null) 
    { OnBeforeCommit(this, EventArgs.Empty); } 

    RepositoriesContexts.Each(context => context.SaveChanges()); 

    if (OnCommit != null) 
    { OnCommit(this, EventArgs.Empty); } 
} 

每個UnitOfWork都有自己的上下文實例,所有的實例都保存在這裏。

然後,我確實創造了用下面的代碼頭:

private Header CreateHeader(Chapter chapter, string header) 
{ 
    var retrievedHeader = UnitOfWork.HeaderRepository.Get(x => x.Name.Equals(header, StringComparison.InvariantCultureIgnoreCase) && 
                  x.Chapter.Id == chapter.Id); 

    if (retrievedHeader == null) 
    { 
     UnitOfWork.HeaderRepository.Insert(new Header { Name = header, Chapter = chapter }); 
     UnitOfWork.Commit(); 

     retrievedHeader = UnitOfWork.HeaderRepository.Get(x => x.Name.Equals(header, StringComparison.InvariantCultureIgnoreCase) && 
                  x.Chapter.Id == chapter.Id); 
    } 

    return retrievedHeader; 
} 

現在,讓我們說,我通過這種方法添加章節和製作的節段的ID爲1 然後我通過該章到標題,但這裏不是用正確的章節創建標題,而是添加新章節並鏈接到創建的標題。

這使我瘋狂。

回答

2

每個UnitOfWork都有自己的上下文實例,所有的實例都保存在這裏。

您必須跨所有存儲庫共享單個上下文。

+0

不是UnitOfWork的基本思想,每個存儲庫都有自己的上下文實例嗎? – Complexity 2014-10-06 13:41:33

+2

@Complexity否,UnitOfWork的基本思想是將一堆存儲庫綁定到一個可管理的上下文實例中。 'DbContext'已經是工作風格類的一個單元。您可能希望以接口的形式將其抽象化以將其展示給您的消費者,但對於EF,您不應該在其上面使用第二個工作單元層。 AFAIK,編號: – 2014-10-06 13:42:40

+0

工作單元模式的想法是,您可以在單個操作中「編寫」一個包含所有插入,更新和刪除的工作,即提交。 – Maarten 2014-10-06 13:43:23