定義查詢 - EF 設計工具
本逐步解說示範如何使用 EF Designer,將定義查詢和對應的實體類型新增至模型。 定義查詢通常用來提供與資料庫檢視所提供的功能類似的功能,但檢視是在模型中定義,而不是資料庫。 定義查詢可讓您執行 .edmx 檔案之 DefiningQuery 元素中指定的 SQL 語句。 如需詳細資訊,請參閱 SSDL 規格 中的 DefiningQuery 。
使用定義查詢時,您也必須在模型中定義實體類型。 實體類型是用來呈現定義查詢所公開的資料。 請注意,透過此實體類型呈現的資料是唯讀的。
您不能將參數化查詢做為定義查詢來執行。 不過,將用於呈現資料的實體類型之 Insert、Update 和 Delete 等函式對應至預存程序,即可更新資料。 如需詳細資訊,請參閱 使用預存程式 插入、更新和刪除。
本主題說明如何執行下列工作。
- 新增定義查詢
- 將實體類型新增至模型
- 將定義查詢對應至實體類型
必要條件
若要完成這個逐步解說,您將需要:
- 最新版的 Visual Studio。
- School 範例資料庫 。
設定專案
本逐步解說是使用 Visual Studio 2012 或更新版本。
- 開啟 Visual Studio。
- 在 [檔案] 功能表上,指向 [開新檔案] ,然後按一下 [專案] 。
- 在左窗格中,按一下 [Visual C# ],然後選取 [主控台應用程式 ] 範本。
- 輸入 DefiningQuerySample 作為專案的名稱,然後按一下 [ 確定 ]。
根據學校資料庫建立模型
以滑鼠右鍵按一下方案總管中的專案名稱,指向 [ 新增 ],然後按一下 [ 新增專案 ]。
從左側功能表中選取 [資料 ],然後在 [範本] 窗格中選取 [ADO.NET 實體資料模型 ]。
針對檔案名輸入 DefiningQueryModel.edmx ,然後按一下 [ 新增 ]。
在 [選擇模型內容] 對話方塊中,選取 [從資料庫 產生],然後按 [下一步 ]。
按一下 [新增連線。 在 [連線ion 屬性] 對話方塊中,輸入伺服器名稱 (例如 , localdb)\mssqllocaldb ),選取驗證方法,輸入 School 以取得資料庫名稱,然後按一下 [ 確定 ]。 [選擇您的資料連線] 對話方塊會使用您的資料庫連線設定來更新。
在 [選擇您的資料庫物件] 對話方塊中,核取 [ 資料表] 節點。 這會將所有資料表新增至 學校 模型。
按一下完成。
在 方案總管中,以滑鼠右鍵按一下 DefiningQueryModel.edmx 檔案,然後選取 [ 開啟 With... ]。
選取 [ XML(文本) 編輯器 ]。
如果出現下列訊息提示,請按一下 [是 ]:
新增定義查詢
在此步驟中,我們將使用 XML 編輯器,將定義查詢和實體類型新增至 .edmx 檔案的 SSDL 區段。
- 將 EntitySet 元素新增至 .edmx 檔案的 SSDL 區段(第 5 行至 13 行)。 指定下列專案:
- 只指定 EntitySet 元素的 Name 和 EntityType 屬性。
- EntityType 屬性中 會使用實體類型的完整名稱。
- 要執行的 SQL 語句是在 DefiningQuery 元素中 指定。
<!-- SSDL content -->
<edmx:StorageModels>
<Schema Namespace="SchoolModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
<EntityContainer Name="SchoolModelStoreContainer">
<EntitySet Name="GradeReport" EntityType="SchoolModel.Store.GradeReport">
<DefiningQuery>
SELECT CourseID, Grade, FirstName, LastName
FROM StudentGrade
JOIN
(SELECT * FROM Person WHERE EnrollmentDate IS NOT NULL) AS p
ON StudentID = p.PersonID
</DefiningQuery>
</EntitySet>
<EntitySet Name="Course" EntityType="SchoolModel.Store.Course" store:Type="Tables" Schema="dbo" />
- 將 EntityType 元素新增至 .edmx 的 SSDL 區段。 檔案,如下所示。 請注意下列事項:
- Name 屬性的值 會對應至上述 EntitySet 元素中 EntityType 屬性的值 ,不過 EntityType 屬性中 會使用實體類型的完整名稱。
- 屬性名稱會對應至 DefiningQuery 元素中 SQL 語句所傳回的資料行名稱(上圖)。
- 在本範例中,實體索引鍵由三個屬性組成,以確保唯一的索引鍵值。
<EntityType Name="GradeReport">
<Key>
<PropertyRef Name="CourseID" />
<PropertyRef Name="FirstName" />
<PropertyRef Name="LastName" />
</Key>
<Property Name="CourseID"
Type="int"
Nullable="false" />
<Property Name="Grade"
Type="decimal"
Precision="3"
Scale="2" />
<Property Name="FirstName"
Type="nvarchar"
Nullable="false"
MaxLength="50" />
<Property Name="LastName"
Type="nvarchar"
Nullable="false"
MaxLength="50" />
</EntityType>
注意
如果您稍後執行 [ 更新模型精靈 ] 對話方塊,將會覆寫對儲存體模型所做的任何變更,包括定義查詢。
將實體類型新增至模型
在此步驟中,我們將使用 EF Designer 將實體類型新增至概念模型。 請注意以下要點:
- 實體 的名稱會對應至上述 EntitySet 元素中 EntityType 屬性的值 。
- 屬性名稱會對應至上述 DefiningQuery 元素中 SQL 語句所傳回的資料行名稱。
- 在本範例中,實體索引鍵由三個屬性組成,以確保唯一的索引鍵值。
在 EF 設計工具中開啟模型。
按兩下 DefiningQueryModel.edmx。
對下列訊息說 是 :
[實體設計工具] 會顯示為編輯模型提供設計介面。
- 以滑鼠右鍵按一下設計工具介面,然後選取 [ 新增實體 > ...]。
- 指定 Key 屬性 的機構名稱和 CourseID 的 GradeReport 。
- 以 滑鼠右鍵按一下 GradeReport 實體,然後選取 [ 新增新的 純 > 量屬性 ]。
- 將屬性的預設名稱變更為 FirstName 。
- 新增另一個純量屬性,並指定 名稱的 LastName 。
- 新增另一個純量屬性,並指定 Name 的 Grade 。
- 在 [ 屬性] 視窗中,將 Grade 的 Type 屬性變更為 [十進位 ]。
- 選取 FirstName 和 LastName 屬性。
- 在 [ 屬性] 視窗中,將 EntityKey 屬性值變更為 True 。
因此,下列元素已新增至 .edmx 檔案的 CSDL 區段。
<EntitySet Name="GradeReport" EntityType="SchoolModel.GradeReport" />
<EntityType Name="GradeReport">
. . .
</EntityType>
將定義查詢對應至實體類型
在此步驟中,我們將使用 [對應詳細資料] 視窗來對應概念和儲存體實體類型。
- 以滑鼠右鍵按一下 設計介面上的 GradeReport 實體,然後選取 [ 資料表對應 ]。
[ 對應詳細資料 ] 視窗隨即顯示。 - 從 [ < 新增資料表] 或 [檢視] > 下拉式清單中選取 [GradeReport ](位於 [資料表 ] 下方 )。
概念和儲存體 GradeReport 實體類型之間的預設對應隨即出現。
因此, EntitySetMapping 元素會新增至 .edmx 檔案的對應區段。
<EntitySetMapping Name="GradeReports">
<EntityTypeMapping TypeName="IsTypeOf(SchoolModel.GradeReport)">
<MappingFragment StoreEntitySet="GradeReport">
<ScalarProperty Name="LastName" ColumnName="LastName" />
<ScalarProperty Name="FirstName" ColumnName="FirstName" />
<ScalarProperty Name="Grade" ColumnName="Grade" />
<ScalarProperty Name="CourseID" ColumnName="CourseID" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
- 編譯應用程式。
在您的程式碼中呼叫定義查詢
您現在可以使用 GradeReport 實體類型來執行定義查詢。
using (var context = new SchoolEntities())
{
var report = context.GradeReports.FirstOrDefault();
Console.WriteLine("{0} {1} got {2}",
report.FirstName, report.LastName, report.Grade);
}