2009-07-09 133 views
6

你將如何建立這個查詢與實體框架:實體框架查詢XML

SELECT * 
FROM TreeNodes 
WHERE data.value('(/edumatic/assessmentItem/@type)[1]', 'nvarchar(max)') like 'multiplechoice1' 

數據列是XML。顯然,這是轉換成實體框架的字符串...

這是我的開始,但在這裏,我不知道如何添加在那裏......

var query = from e in edumatic3Context.TreeNodes 
         where e.Data.??????? 
         select e; 

      foreach (var treeNode in query) 
       Console.WriteLine("{0} {1} {2} {3}", treeNode.TreeNodeId, treeNode.Name, treeNode.Type, treeNode.DateChanged); 

我也試過類似下面的代碼,但沒有工作,要麼:

var sql = "SELECT VALUE treeNode FROM TreeNodes as treeNode WHERE data.value('(/edumatic/assessmentItem/@type)[1]', 'nvarchar(max)') like 'multiplechoice1'"; 
      var query = edumatic3Context.CreateQuery<TreeNodes>(sql); 

foreach(...) 

回答

10

實體框架的查詢語言(LINQ to Entities和eSQL)都不直接支持嵌套的XML查詢。所以你不能做這種事情。除非在調用AsEnumerable()之後運行XML查詢,但從性能角度來看,這當然是不合乎需要的。

話雖如此,你可以寫一個存儲函數在SSDL中爲你做這個過濾器。

在XML編輯器中打開EDMX文件,然後嘗試在StorageModel部分(即SSDL)下添加一個元素。該存儲函數的<CommandText>(我認爲這就是它所稱的)是您可以編寫適當的T-SQL的位置,您也可以參考該函數的參數。對不起,我沒有這個方便的例子。

做完,你可以調用存儲功能的ESQL即是這樣的:

SELECT VALUE treeNode FROM TreeNodes as treeNode WHERE 
StorageModelNamespace.MyXmlWrapperFunctionForNVarchar('(/edumatic/assessmentItem/@type)[1]', treeNode.Data) LIKE 'multiplechoice1' 

在.NET 4.0中,你還可以在.NET中寫一個存根函數,以便您可以調用該函數在LINQ太:

[EdmFunction("StorageModelNamespace", "MyXmlWrapperFunctionForNVarchar"] 
public static string MyXmlHelper(string path, string data) 
{ 
    throw new NotImplementedException("You can only call this function in a LINQ query"); 
} 

則是這樣的:

var query = from e in edumatic3Context.TreeNodes 
      where MyXmlHelper("(/edumatic/assessmentItem/@type)[1]", e.Data) 
       .StartsWith("multiplechoice1") 
      select e; 

請注意以上所有代碼都只是僞代碼,我沒有真正測試過,我只是試圖幫助您開始使用。

希望這有助於

亞歷

項目經理實體框架團隊

+0

你能推薦一本書來學習實體框架(帶存儲功能的例子......)?謝謝。 – 2009-07-10 13:44:29

2

兩個選擇:

  1. 寫一個進程,它返回的所有數據需要映射到實體類型,並將SQL放在那裏。此方法可以在數據庫服務器上使用XML索引。
  2. 檢索客戶端上的數據,然後構建XML文檔並使用LINQ to XML。方便程序員,但不能使用XML索引。

LINQ to Entities不知道DB服務器的XML功能。