本主題說明如何利用實體框架設計器(EF Designer)映射複雜型態,以及如何查詢包含複雜型態屬性的實體。
下圖顯示使用 EF Designer 時主要使用的視窗。
備註
當您建立概念模型時,錯誤清單中可能會出現關於未映射實體與關聯的警告。 你可以忽略這些警告,因為當你選擇從模型產生資料庫後,錯誤就會消失。
什麼是複型
複雜類型是實體類型的非純量屬性,可讓純量屬性組織在實體內。 與實體類似,複型態由純量性質或其他複型性質組成。
當你處理代表複雜型態的物件時,請注意以下事項:
- 複雜型別沒有鍵,因此無法獨立存在。 複雜型態只能作為實體型別或其他複雜型態的屬性存在。
- 複雜型別無法參與關聯,也無法包含導航屬性。
- 複雜型態屬性不可能是 空的。 當呼叫 DbContext.SaveChanges 並遇到一個空複數物件時,會發生 **InvalidOperationException。 複雜物體的純量性質可以為 零。
- 複型別不能從其他複型繼承。
- 你必須將複雜型態定義為 一個類別。
- EF 會偵測到複雜型態物件上成員的變更,當呼叫 DbContext.DetectChanges 時。 當以下成員被呼叫時,Entity Framework 會自動呼叫 DetectChanges : DbSet.Find、 DbSet.Local、 DbSet.Remove、 DbSet.Add、 DbSet.Attach、 DbContext.SaveChanges、 DbContext.GetValidationErrors、 DbContext.Entry、 DbChangeTracker.Entry。
將實體的屬性重構為新的複合型態
如果你的概念模型中已有實體,建議將部分屬性重構成複雜型態屬性。
在設計器表面,選擇一個或多個屬性(不含導覽屬性),然後右鍵點選「 重構 -> 移動到新複雜型別」。
模型 瀏覽器中會新增一個包含所選屬性的複雜型態。 複數型態會被賦予預設名稱。
新建立的複雜屬性會取代所選屬性。 所有土地地圖均被保存。
建立新的複合型別
你也可以建立一個新的複雜型別,但不包含現有實體的屬性。
在模型瀏覽器中右鍵點擊 Complex Types 資料夾,指向 AddNew Complex Type...。 或者,你也可以選擇 Complex Types 資料夾,然後按下鍵盤上的 Insert 鍵。
資料夾中會新增一個帶有預設名稱的複雜類型。 你現在可以為該類型新增屬性。
為複雜型態新增屬性
複型態的性質可以是純量型態或現有的複型態。 然而,複雜型態屬性不能有循環參考。 例如,複雜型態的 OnsiteCourseDetails 不能有複雜型別 OnsiteCourseDetails 的屬性。
你可以用以下列出的任何方式將屬性添加到複合類型。
在模型瀏覽器中右鍵點擊一個複雜型態,點到 新增,再點到標 量屬性 或 複雜屬性,最後選擇想要的屬性類型。 或者,你也可以選擇一個複雜的類型,然後按下鍵盤上的 插入 鍵。
複合型態會新增一個屬性,並設定預設名稱。
或者——
在 EF Designer 表面上右鍵點擊實體屬性並選擇 複製,然後在 模型瀏覽器 中右鍵點擊複雜類型並選擇 貼上。
重新命名複雜型別
當你重新命名一個複雜型態時,整個專案中對該型別的所有引用都會被更新。
慢慢地在 模型瀏覽器中雙擊一個複雜的字型。 名稱會被選取並進入編輯模式。
或者——
在 模型瀏覽器 中右鍵點選一個複雜型態,然後選擇 「重新命名」。
或者——
在模型瀏覽器中選擇一個複雜類型,並按 F2 鍵。
或者——
在 模型瀏覽器 中右鍵點擊複雜型態,並選擇 屬性。 在 屬性 視窗中編輯名稱。
將現有的複雜型態加入實體,並將其屬性映射到資料表欄位
右鍵點擊一個實體,指向 新增,然後選擇 複雜屬性。 在實體中加入一個帶有預設名稱的複雜型態屬性。 預設類型(從現有複雜類型中選擇)會被指派給該屬性。
在 屬性 視窗中為該屬性指派所需的類型。 在將複雜型態屬性加入實體後,你必須將其屬性映射到資料表欄位。
在設計表面或 模型瀏覽器 中右鍵點擊實體類型,選擇 表格映射。 表格映射會顯示在 映射細節 視窗中。
展開 映射到 <資料表名稱> 節點。 會出現一個 欄位映射 節點。
展開 欄位映射 節點。 表格中會出現所有欄位的清單。 欄位所對應的預設屬性(如有)會列在 「值/屬性 」標題下。
選擇你想映射的欄位,然後右鍵點擊對應 的值/屬性 欄位。 會顯示一個下拉選單,列出所有標量屬性。
選擇合適的房產。
對每個表格欄位重複步驟6和7。
備註
要刪除欄位映射,選擇你想要映射的欄位,然後點選值 /屬性 欄位。 接著,從下拉選單中選擇 刪除 。
將函式匯入映射到複雜型態
函式匯入是基於儲存程序。 要將函式匯入映射到複雜型態,對應的儲存程序回傳的欄位必須在數量上與該複雜型態的屬性相符,且儲存型態必須與屬性類型相容。
雙擊你想映射到複雜型別的匯入函式。
請填寫新函式匯入的設定,如下:
請在 儲存程序名稱 欄位中指定你要建立函式匯入的儲存程序。 此欄位是一個下拉選單,顯示儲存模型中所有儲存程序。
請在 函式匯入名稱 欄位指定函式匯入名稱。
選擇 Complex 作為返回類型,然後從下拉選單中選擇合適的類型來指定特定的複數返回類型。
按一下 確定。 函式匯入條目會在概念模型中創建。
自訂函式匯入欄位映射
- 在模型瀏覽器中右鍵點選「匯入函式」,然後選擇 「函數匯入映射」。 映射 細節 視窗會出現,顯示匯入函式的預設映射。 箭頭表示欄位值與屬性值之間的對應。 預設情況下,欄位名稱假設與複雜型態的屬性名稱相同。 預設欄位名稱以灰色文字顯示。
- 如有必要,將欄位名稱更改為與匯入函式所對應的儲存程序返回的欄位名稱一致。
刪除複雜型態
當你刪除一個複雜型態時,該型別會從概念模型中被刪除,該型別的所有實例的映射也會被刪除。 然而,對該類型的引用不會被更新。 例如,若某實體具有 ComplexType1 的複雜型態屬性,且 ComplexType1 在 模型瀏覽器中被刪除,對應的實體屬性則不會更新。 模型無法驗證,因為它包含一個參考已刪除複雜型別的實體。 你可以使用實體設計器更新或刪除對已刪除複雜型別的引用。
在模型瀏覽器中右鍵點擊複雜類型,然後選擇 刪除。
或者——
在模型瀏覽器中選擇一個複雜類型,然後按下鍵盤上的 Delete 鍵。
查詢包含複雜型態屬性的實體
以下程式碼說明如何執行一個查詢,回傳包含複雜型態屬性的實體類型物件集合。
using (SchoolEntities context = new SchoolEntities())
{
var courses =
from c in context.OnsiteCourses
order by c.Details.Time
select c;
foreach (var c in courses)
{
Console.WriteLine("Time: " + c.Details.Time);
Console.WriteLine("Days: " + c.Details.Days);
Console.WriteLine("Location: " + c.Details.Location);
}
}