2017-05-23 60 views
0

我查詢我的交付和包括它的一個特性(材料類型)和它返回的一切,除了我的材料類型具有交貨清單良好。因此其退貨交付兄弟姐妹。EF是包括兒童的參考回到父母的兄弟姐妹

這裏是我的課:

public class Delivery 
{ 
    public int DeliveryId { get; set; } 
    public DateTime DeliveryDate { get; set; } 
    ... 
    public int MaterialTypeId { get; set; } 
    public virtual MaterialType MaterialType { get; set; } 
} 

public class MaterialType 
{ 
    public int MaterialTypeId { get; set; } 
    public string Name { get; set; } 
    ... 
    public virtual ICollection<Delivery> Deliveries { get; set; } 
} 

這裏是我的交貨日期範圍

var deliveries = DataStore.Filter<Delivery>(i => 
       i.DeliveryDate >= startDate && i.DeliveryDate < endDate 
       ,new string[] { "MaterialType" }) // Includes 
       .OrderByDescending(i => i.DeliveryDate).ToList(); 

public virtual IQueryable<T> Filter<T>(Expression<Func<T, bool>> predicate, string[] includes = null) where T : class 
{ 
    IQueryable<T> set = dbContext.Set<T>(); 
    if (includes != null && includes.Count() > 0) 
    { 
     foreach (var include in includes) 
     { 
      set = set.Include(include); 
     } 
    } 
    return set.Where<T>(predicate).AsQueryable<T>(); 
} 

這裏查詢是我得到的查詢和Delivery.MaterialType回結果。交付正在與原始交付的兄弟姐妹一起填充。

[{ 
    "DeliveryId": 1, 
    "DeliveryDate": "2017-05-22", 
    "MaterialTypeId": 2, 
    "MaterialType": { 
     "MaterialTypeId": 2, 
     "Name": "Bulk", 
     "Deliveries": [{ 
      "DeliveryId": 2, 
      "DeliveryDate": "2017-05-22", 
      "MaterialTypeId": 2, 
     }, 
     { 
      "DeliveryId": 3, 
      "DeliveryDate": "2017-05-22", 
      "MaterialTypeId": 2, 
     }] 
    } 
}] 

延遲加載設置爲禁用。

dbContext.Configuration.LazyLoadingEnabled = false; 

有沒有辦法阻止MaterialTypes填充交付?

+0

這是('Include')裝載多麼渴望工作(儘管不應包括兄弟姐妹)。在你的情況下,這個集合可能已經被* lazy loading *填充了(這是我看到的'虛擬')。 –

+0

@IvanStoev我注意到的是,MaterialType下的交付是由我上面的過濾器(日期範圍)驅動的。 – Miguel

回答

2

我不知道延遲加載這裏有毛病,而這可能需要做的與自動裝配了關係的東西。

所以我們可以說,你有交付與材料類型A,並與材料類型A也傳遞B中。如果您針對交貨發出查詢幷包含物料類型,則物料類型A中的交貨清單將同時包含交貨A和交貨B,因爲無論如何它們會作爲查詢的結果加載到上下文中。

禁用延遲加載只告訴訪問屬性時,EF不加載任何的實體,但它並沒有說如何修正了那些已經在上下文實體之間的關係什麼。如果發出使用相同的DbContext對象的多個查詢

相同的情況可能發生:一次運行查詢時,結果被物化,對象是在上下文。因此,如果使用相同的上下文發出另一個查詢,其中一個結果對象具有對之前加載的實體的引用,則會根據上下文中的對象自動填充導航屬性。

+0

有什麼我可以做,以避免這些屬性?我有一個解決方案,通過迭代項目並清除值。 – Miguel

+0

不錯的建議!我完全忘記了實體關係修正。 –

+1

@Miguel說實話,我不確定。您可以將AsNoTracking()方法調用添加到查詢中,但只有在多個查詢出現問題時纔可以使用該方法。如果由於單個查詢而導致被修正的實體被實現,我不確定它是否可以工作(說實話,不知道它是否能解決問題)。您也可以嘗試將上下文的AutoDetectChangesEnabled屬性設置爲false,但是再次不確定這是否真的解決了問題(當然也不是如果您將新實體添加到上下文中),但它可能值得一試。 –

0

你序列化對象有延遲加載啓用,所以它填充的所有屬性。禁用延遲加載這樣的查詢之前:

DataStore.Configuration.LazyLoadingEnabled = false; 
+0

謝謝,您的迴應!我已經將lazy loading屬性設置爲false。用這一點信息更新我的問題。 – Miguel

+0

如果延遲加載已被禁用,它不應該做你要求的。拋出一些調試代碼以確保它實際上被禁用,並且DataStore正在使用禁用了「延遲加載」的相同dbContext。你可以嘗試從你的模型中刪除'virtual'關鍵字,這也應該告訴EF你不想延遲加載。 –

+0

剛剛證實延遲加載設置爲false。我還刪除了虛擬關鍵字,但仍遇到同樣的問題。 – Miguel