2012-01-23 67 views
0

在我的Entityframework模型中,我有一個類型/表「ModelElement」,它鏈接到一個類型/表「ElementToComponentMapping」。導航/外鍵是「ModelID」和「ElementNo」。EntityFramework/LINQ - 從關聯表/類型獲取過濾內容

我需要編寫一個方法,該方法根據某些過濾條件返回ModelElement的一個實例,其中還包含鏈接到ModelElement實例的ElementToComponentMapping的內容。我面臨的挑戰是我還需要過濾從ElementToComponentMapping返回的內容,這意味着它看起來不像我可以使用。包括

所以這不起作用,因爲我無法使用包含/在where子句中導航類型

public ModelElement GetModelElement(int modelID, int modelElementNo, int version) 
{ 
    return (from c in context.ModelElements.Include("ElementToComponentMapping") 
      where c.ModelID == modelID && c.ElementNo == modelElementNo 
       && c.ElementToComponentMappings.Where(m => m.version == version) 
        select c).FirstOrDefault(); 
} 

我的第二個嘗試是第一查詢出的主要「是ModelElement」對象,則查詢出相關的「ElementToComponentMappings」分開,並設置爲「是ModelElement」

的屬性
public ModelElement GetModelElement(int modelID, int modelElementNo, int version) 
{ 
ModelElement newElement = (from c in context.ModelElements 
        where c.ModelID == modelID && c.ElementNo == modelElementNo 
        select c).FirstOrDefault(); 
newElement.ElementToComponentMappings = 
         (from m in context.ElementToComponentMappings 
          where m.ModelID == modelID 
          && m.ElementNo == modelElementNo 
          && m.version == version 
           select m).FirstOrDefault(); 
return newElement; 
} 

但是,這也不起作用,因爲直接查詢「ElementToComponentMappings」對象返回的類型與「ModelElement」對象上的「ElementToComponentMappings」屬性不同。

這似乎是一個簡單的操作 - 獲取外鍵鏈接表的值,在這裏你根據FK表的內容過濾你的內容,所以希望我只是在這裏忽略了一些明顯的東西......?

回答

1

該類型不同,因爲您的newElement.ElementToComponentMappings是集合,但您的查詢僅返回單個實例。

你可以嘗試使用這個:

context.ContextOptions.LazyLoadingEnabled = false; 
var newElement = (from c in context.ModelElements 
        where c.ModelID == modelID && c.ElementNo == modelElementNo 
        select c).FirstOrDefault(); 

var mapping = (from m in context.ElementToComponentMappings 
       where m.ModelID == modelID 
        && m.ElementNo == modelElementNo 
        && m.version == version 
       select m).FirstOrDefault(); 

// now check if newElement.ElementToComponentMappings contains your single item 

您也可以嘗試使用這個:

context.ContextOptions.LazyLoadingEnabled = false; 
var newElement = (from c in context.ModelElements 
        where c.ModelID == modelID && c.ElementNo == modelElementNo 
        select c).FirstOrDefault(); 

((EntityCollection<ElementToComponentMappings>)newElement.ElementToComponentMappings) 
    .CreateSourceQuery() 
    .FirstOrDefault(m.version == version); // You don't need to check FKs here 

// now check if newElement.ElementToComponentMappings contains your single item 

,如果你的類型,代理和延遲加載,因爲這使這些方法都不適用預期的自動關係修正不會將導航屬性標記爲已加載(如果您有延遲加載,則對該屬性的下一次訪問將觸發延遲加載並加載所有其他實體)。

+0

感謝您的輸入,不幸的是還沒有完全實現:在您的第一個建議中,newElement.ElementToComponentMappings屬性在哪裏設置?在第二個建議中,我得到一個錯誤,即ElementToComponentMappings不包含FirstOrDefault的定義,最好的擴展方法重載包含無效參數。關於類型差異,你說得對,ElementToComponentMappings是一個集合 - 這是否意味着我應該調用ToList而不是在某個點? –

+0

在第一種情況下,這是一個竅門。如果一切配置正確,則不需要設置該屬性。它應該被自動填充。第二種情況很奇怪。 'CreateSourceQuery'應該返回'ObjectQuery',它是'IQueryable'的實現,它提供'FirstOrDefault'。只有當你的實體沒有被代理時,你使用'ToList'的方式纔會工作,否則你會得到一些錯誤,你不能指定一個新的集合到導航屬性。 –

+0

+1有用的提示,技巧和見解。最後,我無法得到這種方法的工作,所以這是另一種方式。 –