2012-07-12 56 views
1

我有一個ASP MVC 3應用程序使用實體框架4從SQL Server數據庫訪問數據。EF4 - 分離對象的負載相關實體

我有一個場景,我使用EF4從數據庫加載實體。然後,我可以按照正常情況加載相關實體。第一次加載後,我緩存實體。這要求將其序列化。在下一個請求中,我加載了相同的實體,但這次是從緩存中加載的。這會導致對象從上下文中分離出來,因爲它不是從那裏發起的。然後我無法正常加載相關的實體。

看起來很明顯,原因是該對象與上下文分離,因此未被跟蹤。我知道,當一個對象被上下文跟蹤時,它會跟蹤這些更改並在需要時通過執行實際的SQL語句來應用這些更改。但我不確定附加狀態是否與加載相關實體的能力有關。

好的,這裏有一些細節。這是模型結構。請注意,這是簡化的,並不包括使EF4能夠使用它的所有必要條件。這簡單地展示了結構。

public class Segment 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public SegmentGroup Group { get; set; } 
} 
public class SegmentGroup 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public IEnumerable<Segment> Segments { get; set; } 
} 

然後我可以從數據庫或緩存中獲得一個段。這是在一個Manager類中完成的。再次非常簡化。

public SegmentManager 
{ 
    public Segment GetSegment(Guid id) 
    { 
     string cacheKey = ... //generate specific cache key using Guid id 
     Segment segment = CacheProvider.Get<Segment>(cacheKey); 
     if(segment == null) //does not exist in cache yet - load from db and insert into cache 
     { 
      segment = repo.Find<Segment>(id); //roughly translates to: 
               //segment = dbcontext.Segments.SingleOrDefault(a => a.Id == id); 
      CacheProvider.Add(cacheKey, segment); 
     } 
     else //segment was found in cache - attach to context 
     { 
      repo.Attach<Segment>(segment); //dbcontext.Segments.Attach(segment); 
     } 
     return segment; 
    } 
} 

因此,這則有效地實現我用這個部門經理是這樣的:

public ActionResult SegmentGroupName(Guid segmentId) 
{ 
    Segment segment = SegmentManager.GetSegment(segmentId); //Loaded from DB of Cache 
    return segment.Group.Name; //Group is accesable when segment is loaded from DB, but not from cache 
} 

所以問題是,我可以當段從數據庫加載段訪問的SegmentGroup,但不是從緩存中加載時。

所以我的問題是,我可以做什麼從段緩存加載後,使我能夠訪問相關的實體的段。 我需要一個通用的解決方案,我可以將這個解決方案應用於我的所有模型管理者,因爲所有的東西都是抽象的。 我試圖避免急於加載所有相關的實體或手動加載它們之後的事實,因爲這實際上比不高速緩存更昂貴。我只想讓事情回到緩存之前的狀態。 :)

請注意,代碼演示非常簡單,你需要做出一些現實的假設。

回答

0

聽起來像是我碰到的東西,我稱之爲薛定諤的代碼......我遇到了類似的問題,我將模型傳遞給了我的視圖,但是當試圖訪問相關實體時,到正在關閉的對象上下文。通過在將主實體傳遞給我的視圖之前觀察相關實體,我無需重新打開對象上下文即可解決此問題。

舉例來說,如果我正在處理您的細分和組,這將是以下

Segment segment = repo.Find<Segment>(segmentId); 
var segmentGroup = segment.Group; 

我不打算在此之後做任何事情segmentGroup東西,而僅僅是因爲我發現它,它現在存在。如果沒有事先的觀察,系統不確定如何處理這個問題,因爲還沒有對數據庫進行額外的調用,但是由於在這種情況下已經觀察到,所以Group對象的數據已經與Segment對象相關聯。我知道它存在,但它不存在......我們知道它存在,但我們必須看到它來證明它......因此,爲什麼我將這種情況稱爲薛定諤的代碼...

相關問題