Dieser Artikel wurde maschinell übersetzt.

Datenpunkte

LINQ-Projektionsabfragen und Alternativen in WCF-Diensten

Julie Lerman

Beispielcode herunterladen

Julie LermanDer Referent bei meinem lokalen Benutzergruppe .NET wurde einer LINQ-Abfrage während seiner Sitzung letzten Monat schreiben Wenn ich ihm gefragt werden, “ wie jemals ohne LINQ Leben wir? ” “ Ich habe keine Ahnung, ”, beantwortet er.

Es ist wahr. Da es in Visual Studio 2008 eingeführt wurde, hat der LINQ vorgenommen.solche ein Unterschied in der wir in Microsoft .NET Framework Code. In Kombination mit den vielen neuen Sprachfeatures in Visual Basic und c# eingeführt wurden, ist es eine einheitliche Problem Solver zum Abfragen von in-Memory-Objekte und Datenquellen.

Eine LINQ Fähigkeiten, die ein Segen und ein gelegentliche Quelle der Frustration ist, dass es nach dem Zufallsprinzip strukturierten Daten in anonymen Typen Projekt kann. Wenn Sie einfach eine spezielle Ansicht Ihrer Daten zu erfassen, ohne eine neue Klasse für dieses throwaway Typ deklarieren müssen, sind anonyme Typen eine hervorragende Lösung. LINQ Projektionen und anonyme Typen haben sicherlich uns spoiled. Also warum ich sage, außerdem eine Quelle der Frustration sein können?

Wenn Sie jemals eine LINQ-Projektion in einer Methode verwendet haben, die Daten in einer anderen Methode zurückgegeben werden muss – oder schlimmer noch, in einer Windows Communication Foundation (WCF) Dienst verwendet eine LINQ-Projektion – Sie verstehen können.

Da anonyme Typen throwaway Typen sind, haben keine Deklaration und die nur innerhalb der Methode, in denen Sie erstellt haben, verstanden werden. Wenn Sie eine Abfrage, die eine Liste von anonymen Typen zurückgibt schreiben, besteht keine Möglichkeit zum Definieren einer Methode Ar-gument zu sagen “ ich werde eine Liste der zurückkehren … ” da besteht keine Möglichkeit zur express-“ … von anonyme Typen ”.

Hier ist eine LINQ to Entities-Abfrage mit einer einfachen Projektion:

var custQuery = from c in context.Customers

                 select new {c.CustomerID, Name=c.LastName.Trim() + 

                 ", " + c.FirstName};

Zur Laufzeit die CustQuery-Variable tatsächlich werden einem ObjectQuery-<<>-f__AnonymousType0 <int,string> >.

Das Var (und die alternative Verwendung von Visual Basic Dim) ermöglicht es uns, sofort mit nicht (oder müssen) zu erhalten, dass dieser Typ auszudrücken.

Wenn Sie die Ergebnisse einer Abfrage von einer Methode zurückgeben möchten, ist nur sinnvolle Lösung zum Erstellen einer Klasse zum Darstellen des Typs zurückgegeben werden. Auf diese Weise stellt jedoch den Vorteil des anonymen Typs-Moot. Jetzt Sie mehr Code schreiben müssen, definieren Sie Klassen und (möglicherweise) neue Projekte beinhalten die neuen Klassen, stellen Sie sicher, dass die verschiedenen Assemblys, die mit diesen Klassen und so weiter darauf zugreifen können.

Bis vor kurzem bereitgestellten Datendienste eine zusätzliche Conundrum. In der Reihenfolge nach Projektdaten mussten Sie erstellen einen benutzerdefinierten Vorgang in einem Dienst, eine eigene Abfrage ausführen und einige Ergebnistyp des vordefinierten-Klasse, die vom Client verstanden werden kann.

Wenn Sie mit Webdiensten arbeiten, gibt es viele Szenarios, die mit einer bestimmten Ansicht der Daten arbeiten, ohne Verschieben von größere Typen über die Leitung den Preis bezahlen verwendet werden soll.

Wie sich herausstellt, sind weitere Optionen neben dem Erstellen eines zusätzlichen Typs in Ihrer Domäne, um diese temporäre Anforderung zu erfüllen.

Neue Prognose-Funktion in WCF Data Services

Das Data Services-Update für .NET Framework 3.5 SP1 führt eine Handvoll von leistungsfähigen Funktionen für WCF Data Services, die auch Teil der .NET Framework-4 sind. Unter diesen Features ist die Möglichkeit, Projektionen bei Abfragen in der Datendienste zu verwenden. Es wird dringend empfohlen die WCF Data Services-Team Blogbeitrag auf allen, die in diesem Update unter neue AuscheckenBlogs.msdn.com/astoriateam/Archive/2010/01/27/Data-Services-Update-for-NET-3-5-SP1-available-for-Download.aspx.

Daten Dienste URI-Syntax wurde der $ ausgewählten Operator hinzugefügt. Sie können für die Eigenschaft und sogar Navigation-Eigenschaft Projektion.

Hier ist ein einfaches Beispiel für eine Projektion, die einige skalare Eigenschaften für einen Kunden zusammen mit der SalesOrderHeaders-Navigationseigenschaft abruft:

http://localhost /DataService.svc/Customers(609)
  $select=CustomerID,LastName,FirstName,SalesOrderHeaders&$expand=
  SalesOrderHeaders

Der erweitern-Operator erzwingt umfassen nicht nur eine Verknüpfung zu den Bestellungen, aber die Daten für jede Bestellung sowie die Ergebnisse.

Abbildung 1 zeigt die Ergebnisse dieser Abfrage. Die erweiterten SalesOrderHeaders (mit nur einen einzigen Auftrag) ist gelb hervorgehoben, während die Kundeninformationen in Grün hervorgehoben ist.

Figure 1 Results of a Data Services Query Projection Requesting Three Customer Properties and the Customer’s SalesOrder-Headers
Abbildung 1 Ergebnisse der drei Eigenschaften von Customer und den Kunden SalesOrderHeaders anfordern Prognose für die Abfrage eine Data Services

Die LINQ, REST-Funktion von .NET Framework und Silverlight-Client-APIs für WCF Data Services wurde aktualisiert, sodass Projektionen sowie ermöglichen:

var projectedCust = (from c in context.Customers

                    where c.CustomerID==609

                    select new {c.CustomerID, c.LastName})

                    .FirstOrDefault();

ProjectedCust ist jetzt ein anonymer Typ, den ich in meiner Clientanwendung verwenden kann.

Es ist auch möglich, in bekannte Entitätstypen, Projekt und in einigen Fällen der DataContext kann Verfolgen der Änderungen, die vom Client und zurück durch den Dienst SaveChanges-Methode können diese Änderungen beibehalten werden. Beachten Sie, dass alle fehlenden Eigenschaften mit ihren Standardwerten gefüllt abrufen (oder null, wenn Sie NULL-Werte zulässig sind) und sein in der Datenbank gespeichert.

Erwartetes starke Typen aus einem EDM aktivieren

Wenn Sie eine Entity Framework Entity Data Model (EDM) verwenden, ist eine bequeme Möglichkeit, um zu vermeiden, wenn Sie Sie außerhalb der Methode übergeben, in dem Sie erstellt wurden, mit anonymer Typen hängen.

Das EDM hat eine Zuordnung QueryView aufgerufen. Ich habe viele Clients dies in der Vergangenheit vor dem für die Unterstützung für die Projektion von Daten-Dienste verweist auf. Nicht nur ist es das Problem gut für Datendienste, aber für benutzerdefinierten WCF-Dienste und RIA-Dienste ebenfalls behoben.

Was ist eine QueryView? Es ist eine besondere Art der Zuordnung in den Metadaten für Entity Framework. In der Regel Sie Datenbanktabellen-Eigenschaften einer Entität zuordnen oder Spalten gemäß der Informationsspeicher-Modell unter – (Storage Schema Definition Language, SSDL) – der Metadaten, wie in Abbildung 2.

Figure 2 Mapping Table Columns Directly to Entity Properties
Abbildung 2 Zuordnen von Tabellenspalten direkt auf den Entitätseigenschaften

Eine QueryView können Sie jedoch eine Ansicht über die SSDL-Tabellenspalten anstelle von Zuordnung direkt zu diesen erstellen. Es gibt viele Gründe, eine QueryView zu verwenden. Zu diesen Diensten gehören: Um Ihre Entitäten verfügbar zu machen, als gelesen - nur mit Entitäten in einer Weise, bedingte Filter zuordnen lässt nicht zu oder unterschiedliche Ansichten der Datentabellen, aus der Datenbank bereitzustellen.

Es ist der letzte für diese Zwecke, die ich als Alternative zu anonymen Typen konzentrieren wird häufig selbst projiziert finden Sie in der Anwendung. Ein Beispiel wäre eine Auswahlliste. Warum Rückgabetyp eine gesamte Debitor für eine Dropdownliste, die nur eine ID und den Namen des Kunden benötigt?

Erstellen eine QueryView

Vor dem Erstellen einer QueryView, müssen Sie eine Entität im Modell zu erstellen, das die Form der Ansicht darstellt, die Sie für anstrebt sind – z. B. die CustomerNameAndID-Entität.

Aber Sie können nicht direkt in der Tabelle "Debitor" in der SSDL dieser Entität zugeordnet. Zuordnen von Customer-Entität, und die CustomerNameAndID-Entität zu CustomerID-Spalte der Tabelle würde einen Konflikt erstellen.

Wie Sie eine Ansicht einer Tabelle in Ihrer Datenbank erstellen können, können Sie stattdessen eine Ansicht der SSDL-Kunden direkt in den Metadaten erstellen. Eine QueryView liegt über die SSDL im wahrsten Sinne des Wortes ein Entity SQL-Ausdruck. Der Teil der Zuordnung Spezifikation Sprache (MSL) Metadaten des Modells. Wird keine Designer unterstützt die QueryView erstellt werden, damit Sie ihn direkt in der XML-Datei eingeben müssen.

Da Sie die Informationsspeicher-Schema der Tabelle, dessen Zuordnung zu werden werde empfiehlt sich, welche, finden Sie unter aussieht. Abbildung 3 Listet die SSDL-Beschreibung der Customer-Datenbanktabelle, die Customer-Entität in Metadaten des konzeptionellen Modells, außer für die Verwendung von Datentypen Anbieter ähnelt.

Abbildung 3 Die SSDL-Beschreibung für die Customer-Datenbanktabelle

<EntityType Name="Customer">

  <Key>

    <PropertyRef Name="CustomerID" />

  </Key>

  <Property Name="CustomerID" Type="int" Nullable="false"

            StoreGeneratedPattern="Identity" />

  <Property Name="Title" Type="nvarchar" MaxLength="8" />

  <Property Name="FirstName" Type="nvarchar" Nullable="false" 

            MaxLength="50" />

  <Property Name="MiddleName" Type="nvarchar" MaxLength="50" />

  <Property Name="LastName" Type="nvarchar" Nullable="false" 

            MaxLength="50" />

  <Property Name="Suffix" Type="nvarchar" MaxLength="10" />

  <Property Name="CompanyName" Type="nvarchar" MaxLength="128" />

  <Property Name="SalesPerson" Type="nvarchar" MaxLength="256" />

  <Property Name="EmailAddress" Type="nvarchar" MaxLength="50" />

  <Property Name="Phone" Type="nvarchar" MaxLength="25" />

  <Property Name="ModifiedDate" Type="datetime" Nullable="false" />

  <Property Name="TimeStamp" Type="timestamp" Nullable="false"

            StoreGeneratedPattern="Computed" />

</EntityType>

Ein weiteres wichtiges Element für die QueryView werden der Informationsspeicher des Schemanamespace, ModelStoreContainer. Sie verfügen nun über die einzelnen Teile erforderlich, den QueryView Ausdruck erstellen. Hier ist ein QueryView, dass Projekte die drei Felder aus der SSDL in die Entität CustomerNameAndID erforderlich, dass ich im Modell erstellt:

SELECT VALUE AWModel.CustomerNameAndID(c.CustomerID, c.FirstName, 

        c.LastName) FROM ModelStoreContainer.Customer as c

Übersetzen von Entity SQL auf Englisch: “ Abfragen den Debitor im Schema Informationsspeicher Herausziehen dieser drei Spalten und weisen Sie wieder an mich als Entität CustomerNameAndID. ” AWModel ist der Namespace des konzeptionellen Modells Entität Container. Sie sind erforderlich, um die stark typisierten Namen die CSDL (Conceptual Schema Definition Language) und die SSDL-Typen verwendet werden, die im Ausdruck verwiesen wird.

Solange die Ergebnisse der Projektion (eine ganze Zahl, eine Zeichenfolge und eine Zeichenfolge) das Schema der Zielentität übereinstimmen, wird die Zuordnung erfolgreich ausgeführt. Ich haben versucht, Funktionen und Verkettung innerhalb der Projektion verwenden – Beispiel (c.CustomerID, c.FirstName + c.LastName)—but dies fehlschlägt, mit einem Fehler, die besagt, dass Funktionen nicht zulässig sind. Also bin ich gezwungen, verwenden Sie die Eigenschaften FirstName und LastName, und lassen Sie den Umgang mit Verkettung Client.

Platzieren in den Metadaten der QueryView

Sie müssen den QueryView Ausdruck innerhalb der EntitySetMapping-Element für die Entität, die innerhalb der EntityContainerMapping in den Metadaten platzieren. Abbildung 4 zeigt diese QueryView (gelb hervorgehoben), die unformatierten XML-Daten der Datei EDMX.

Figure 4 A QueryView in the Mappings Section

Abbildung 4 Eine QueryView im Abschnitt "Zuordnungen"

Jetzt mein CustomerNameAndID ist Bestandteil von Mein Modell und werden an alle Consumer zur Verfügung stehen. Und es ist ein weiterer Vorteil der QueryView. Zwar das Ziel dieser QueryView um eine schreibgeschützten Verweisliste zu erstellen, können Sie auch Entitäten aktualisieren, die mithilfe von QueryViews zugeordnet sind. Der Kontext verfolgt Änderungen CustomerNameAndID-Objekte. Entity Framework ist, zwar nicht automatisch generieren einfügen, aktualisieren und Befehle für diese Entität löschen können können Sie gespeicherte Prozeduren zuordnen.

Die Vorteile der QueryView reaping

Nun, da Sie die QueryView im Objektmodell haben, müssen Sie nicht von Projektionen oder anonyme Typen zum Abrufen dieser Ansichten Ihrer Daten abhängen. In WCF Data Services wird CustomerNameAndIDs auf Abfrage, eine gültige Entität festgelegt, wie hier gezeigt:

List<CustomerNameAndID> custPickList = 

  context.CustomerNameAndIDs.ToList();

Keine Projektionen unübersichtlich. Noch besser können Sie Dienstvorgänge in Ihre benutzerdefinierten WCF-Dienste erstellen, die diese stark typisierte Objekt zurückgeben, ohne neue Typen in Ihrer Anwendung und das Projekt in diese zu definieren sind.

public List<CustomerNameAndID> GetCustomerPickList()

    {

      using (var context = new AWEntities())

      {

        return context.CustomerNameAndIDs.OrderBy(

          c => c.LastName).ToList();

      }

    }

Wegen der Einschränkung, die verhindert, dass uns die ersten und letzten Namen in der QueryView verketten, ist es von den Entwicklern, die den Dienst, führen Sie diese Verkettung auf deren Ende verwenden.

WCF RIA-Diensten können ebenfalls von der QueryView profitieren. Möglicherweise möchten Sie eine Methode zum Abrufen einer Auswahlliste Restaurant aus Ihrer Domäne Dienst offen legen. Statt eine zusätzliche Klasse erstellen, indem Sie in der Domäne-Dienst um die voraussichtlichen Eigenschaften darstellen, wird diese Entität RestaurantPickList durch eine QueryView im Modell gesichert, was erleichtert diese Daten zur Verfügung zu stellen:

public IQueryable<RestaurantPickList> GetRestaurantPickList()

    {

      return context.RestaurantPickLists;

    }

QueryViews oder Projektionen – wir haben Sie vorhandenen abgedeckt

Die Möglichkeit zum Projektansichten über Ihre Datentypen ist ein großer Vorteil in Abfragen, und es ist eine großartige Ergänzung WCF Data Services. In jedem Fall, gibt es Situationen, in denen beim Zugang zu diesen Ansichten, ohne dass Projekt und das Ergebnis Freigabe kümmern zu müssen einige Ihrer Codieraufgaben vereinfacht wird.

Ein letzter Hinweis: Wählen Sie mit der Einführung der Fremdschlüssel in der .NET Framework-4-Version von Entity Framework QueryView Listen stellen sogar mehr erkennen, da Sie nur-Lese-Entitäten zurück und einfach Ihre Eigenschaften, verwenden um die foreign Key-Eigenschaften in den Entitäten, die Sie gerade bearbeiten aktualisieren können.  

Julie Lerman ist als Microsoft MVP, .NET-Mentor und Unternehmensberaterin tätig und wohnt in den Bergen von Vermont. Sie hält bei User Groups und Konferenzen in der ganzen Welt Vorträge zum Thema Datenzugriff und anderen Microsoft .NET-Themen. Lerman führt einen Blogs unter thedatafarm.com/blog und ist Autorin des hoch gelobten Titels "Programming Entity Framework" (O’Reilly Media, 2009). Führen Sie ihn auf Twitter: julielerman.

Dank an den folgenden technischen Experten für die Überprüfung dieses Artikels: Alex James