Definiowanie zapytania — Projektant EF
W tym przewodniku pokazano, jak dodać zapytanie definiujące i odpowiadający mu typ jednostki do modelu przy użyciu Projektant EF. Zapytanie definiujące jest często używane do zapewniania funkcji podobnych do tych udostępnianych przez widok bazy danych, ale widok jest zdefiniowany w modelu, a nie w bazie danych. Zapytanie definiujące umożliwia wykonanie instrukcji SQL określonej w elemendacie DefiningQuery pliku edmx. Aby uzyskać więcej informacji, zobacz Definiowaniequery w specyfikacji SSDL.
Podczas definiowania zapytań należy również zdefiniować typ jednostki w modelu. Typ jednostki służy do uwidaczniania danych udostępnianych przez zapytanie definiujące. Należy pamiętać, że dane udostępniane za pośrednictwem tego typu jednostki są tylko do odczytu.
Nie można wykonywać zapytań sparametryzowanych jako definiujących zapytania. Dane można jednak zaktualizować przez mapowanie funkcji wstawiania, aktualizowania i usuwania typu jednostki, które wyświetlają dane w procedurach składowanych. Aby uzyskać więcej informacji, zobacz Wstawianie, aktualizowanie i usuwanie za pomocą procedur składowanych.
W tym temacie przedstawiono sposób wykonywania następujących zadań.
- Dodawanie zapytania definiującego
- Dodawanie typu jednostki do modelu
- Mapuj zapytanie definiujące na typ jednostki
Wymagania wstępne
W celu wykonania instrukcji w tym przewodniku potrzebne są następujące elementy:
- Najnowsza wersja programu Visual Studio.
- Przykładowa baza danych School.
Konfigurowanie projektu
Ten przewodnik korzysta z programu Visual Studio 2012 lub nowszego.
- Otwórz program Visual Studio.
- W menu Plik wskaż polecenie Nowy, a następnie kliknij pozycję Projekt.
- W okienku po lewej stronie kliknij pozycję Visual C#, a następnie wybierz szablon Aplikacja konsolowa.
- Wprowadź wartość DefiningQuerySample jako nazwę projektu, a następnie kliknij przycisk OK.
Tworzenie modelu na podstawie bazy danych szkoły
Kliknij prawym przyciskiem myszy nazwę projektu w Eksplorator rozwiązań, wskaż polecenie Dodaj, a następnie kliknij pozycję Nowy element.
Wybierz pozycję Dane z menu po lewej stronie, a następnie wybierz pozycję ADO.NET Model danych jednostki w okienku Szablony.
Wprowadź wartość DefiningQueryModel.edmx jako nazwę pliku, a następnie kliknij przycisk Dodaj.
W oknie dialogowym Wybieranie zawartości modelu wybierz pozycję Generuj z bazy danych, a następnie kliknij przycisk Dalej.
Kliknij pozycję Nowy Połączenie ion. W oknie dialogowym Właściwości Połączenie ion wprowadź nazwę serwera (na przykład (localdb)\mssqllocaldb), wybierz metodę uwierzytelniania, wpisz School jako nazwę bazy danych, a następnie kliknij przycisk OK. Okno dialogowe Wybieranie Połączenie danych zostanie zaktualizowane przy użyciu ustawienia połączenia z bazą danych.
W oknie dialogowym Wybieranie obiektów bazy danych zaznacz węzeł Tabele . Spowoduje to dodanie wszystkich tabel do modelu School .
Kliknij przycisk Finish (Zakończ).
W Eksplorator rozwiązań kliknij prawym przyciskiem myszy plik DefiningQueryModel.edmx i wybierz polecenie Otwórz za pomocą....
Wybierz pozycję Edytor XML (tekst).
Kliknij przycisk Tak , jeśli zostanie wyświetlony monit z następującym komunikatem:
Dodawanie zapytania definiującego
W tym kroku użyjemy edytora XML, aby dodać zapytanie definiujące i typ jednostki do sekcji SSDL pliku edmx.
- Dodaj element EntitySet do sekcji SSDL pliku edmx (wiersz 5 do 13). Określ następujące elementy:
- Określono tylko atrybuty Name i EntityType elementu EntitySet.
- W pełni kwalifikowana nazwa typu jednostki jest używana w atrybucie EntityType .
- Instrukcja SQL do wykonania jest określona w elemecie 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" />
- Dodaj element EntityType do sekcji SSDL pliku edmx. plik, jak pokazano poniżej. Zwróć uwagę na następujące kwestie:
- Wartość atrybutu Name odpowiada wartości atrybutu EntityType w powyższym elemecie EntitySet, chociaż w pełni kwalifikowana nazwa typu jednostki jest używana w atrybucie EntityType.
- Nazwy właściwości odpowiadają nazwam kolumn zwracanych przez instrukcję SQL w elemecie DefiningQuery (powyżej).
- W tym przykładzie klucz jednostki składa się z trzech właściwości, aby zapewnić unikatową wartość klucza.
<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>
Uwaga
Jeśli później uruchomisz okno dialogowe Kreator aktualizacji modelu, wszelkie zmiany wprowadzone w modelu magazynu, w tym definiowanie zapytań, zostaną zastąpione.
Dodawanie typu jednostki do modelu
W tym kroku dodamy typ jednostki do modelu koncepcyjnego przy użyciu Projektant EF. Należy zwrócić uwagę na następujące kwestie:
- Nazwa jednostki odpowiada wartości atrybutu EntityType w powyższym elemecie EntitySet.
- Nazwy właściwości odpowiadają nazwam kolumn zwracanych przez instrukcję SQL w powyższym elemecie DefiningQuery .
- W tym przykładzie klucz jednostki składa się z trzech właściwości, aby zapewnić unikatową wartość klucza.
Otwórz model w Projektant EF.
Kliknij dwukrotnie plik DefiningQueryModel.edmx.
Powiedz tak w następującym komunikacie:
Zostanie wyświetlona Projektant Jednostka, która udostępnia powierzchnię projektową do edycji modelu.
- Kliknij prawym przyciskiem myszy powierzchnię projektanta i wybierz polecenie Dodaj nową> jednostkę....
- Określ klasyRaport dla nazwy jednostki i CourseID dla właściwości Key.
- Kliknij prawym przyciskiem myszy jednostkę GradeReport i wybierz polecenie Dodaj nową właściwość> skalarną.
- Zmień domyślną nazwę właściwości na FirstName.
- Dodaj kolejną właściwość skalarną i określ nazwę LastName .
- Dodaj kolejną właściwość skalarną i określ klasę dla nazwy.
- W oknie Właściwości zmień właściwość Type klasy na Decimal.
- Wybierz właściwości FirstName i LastName.
- W oknie Właściwości zmień wartość właściwości EntityKey na True.
W rezultacie następujące elementy zostały dodane do sekcji CSDL pliku edmx.
<EntitySet Name="GradeReport" EntityType="SchoolModel.GradeReport" />
<EntityType Name="GradeReport">
. . .
</EntityType>
Mapuj zapytanie definiujące na typ jednostki
W tym kroku użyjemy okna Szczegóły mapowania, aby zamapować typy jednostek koncepcyjnych i magazynowych.
- Kliknij prawym przyciskiem myszy jednostkę GradeReport na powierzchni projektowej i wybierz pozycję Mapowanie tabeli.
Zostanie wyświetlone okno Szczegóły mapowania. - Wybierz pozycję GradeReport z listy rozwijanej <Dodaj tabelę lub Widok> (znajdującą się w obszarze Tabelas).
Wyświetlane są domyślne mapowania między typem jednostki GradeReport koncepcyjnym a magazynem.
W rezultacie element EntitySetMapping zostanie dodany do sekcji mapowania pliku 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>
- Skompiluj aplikację.
Wywoływanie zapytania definiującego w kodzie
Teraz można wykonać zapytanie definiujące przy użyciu typu jednostki GradeReport .
using (var context = new SchoolEntities())
{
var report = context.GradeReports.FirstOrDefault();
Console.WriteLine("{0} {1} got {2}",
report.FirstName, report.LastName, report.Grade);
}