定義查詢 - EF 設計工具

本逐步解說示範如何使用 EF Designer,將定義查詢和對應的實體類型新增至模型。 定義查詢通常用來提供與資料庫檢視所提供的功能類似的功能,但檢視是在模型中定義,而不是資料庫。 定義查詢可讓您執行 .edmx 檔案之 DefiningQuery 元素中指定的 SQL 語句。 如需詳細資訊,請參閱 SSDL 規格 中的 DefiningQuery

使用定義查詢時,您也必須在模型中定義實體類型。 實體類型是用來呈現定義查詢所公開的資料。 請注意,透過此實體類型呈現的資料是唯讀的。

您不能將參數化查詢做為定義查詢來執行。 不過,將用於呈現資料的實體類型之 Insert、Update 和 Delete 等函式對應至預存程序,即可更新資料。 如需詳細資訊,請參閱 使用預存程式 插入、更新和刪除。

本主題說明如何執行下列工作。

  • 新增定義查詢
  • 將實體類型新增至模型
  • 將定義查詢對應至實體類型

必要條件

若要完成這個逐步解說,您將需要:

設定專案

本逐步解說是使用 Visual Studio 2012 或更新版本。

  • 開啟 Visual Studio。
  • [檔案] 功能表上,指向 [開新檔案] ,然後按一下 [專案]
  • 在左窗格中,按一下 [Visual C# ],然後選取 [主控台應用程式 ] 範本。
  • 輸入 DefiningQuerySample 作為專案的名稱,然後按一下 [ 確定 ]。

 

根據學校資料庫建立模型

  • 以滑鼠右鍵按一下方案總管中的專案名稱,指向 [ 新增 ],然後按一下 [ 新增專案 ]。

  • 從左側功能表中選取 [資料 ],然後在 [範本] 窗格中選取 [ADO.NET 實體資料模型 ]。

  • 針對檔案名輸入 DefiningQueryModel.edmx ,然後按一下 [ 新增 ]。

  • 在 [選擇模型內容] 對話方塊中,選取 [從資料庫 產生],然後按 [下一步 ]。

  • 按一下 [新增連線。 在 [連線ion 屬性] 對話方塊中,輸入伺服器名稱 (例如 , localdb)\mssqllocaldb ),選取驗證方法,輸入 School 以取得資料庫名稱,然後按一下 [ 確定 ]。 [選擇您的資料連線] 對話方塊會使用您的資料庫連線設定來更新。

  • 在 [選擇您的資料庫物件] 對話方塊中,核取 [ 資料表] 節點。 這會將所有資料表新增至 學校 模型。

  • 按一下完成

  • 在 方案總管中,以滑鼠右鍵按一下 DefiningQueryModel.edmx 檔案,然後選取 [ 開啟 With... ]。

  • 選取 [ XML(文本) 編輯器 ]。

    XML Editor

  • 如果出現下列訊息提示,請按一下 [是 ]:

    Warning 2

 

新增定義查詢

在此步驟中,我們將使用 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。

  • 對下列訊息說

    Warning 2

 

[實體設計工具] 會顯示為編輯模型提供設計介面。

  • 以滑鼠右鍵按一下設計工具介面,然後選取 [ 新增實體 > ...]。
  • 指定 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 實體類型之間的預設對應隨即出現。
    Mapping Details3

因此, 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);
    }