Verwendet Entity Framework / LINQ to SQL Data Binding die Reflektion?

9

Verzeihen Sie mir, wenn das schon einmal gefragt wurde; Ich habe eine Suche durchgeführt, konnte aber nichts finden, was speziell auf diese Frage geantwortet hat, aber ich wäre glücklich, verwiesen zu werden.

Ich schaue mir sowohl das Entity Framework als auch LINQ to SQL an, und während ich die Systeme (und natürlich die LINQ-Integration) mag, bin ich dem Aspekt der Datenbindung etwas skeptisch gegenüber. Ich habe die Abfrageergebnisse genommen und inspiziert, und sie scheinen nicht die standardmäßigen .NET-Listenbindungsschnittstellen zu implementieren ( IBindingList und noch wichtiger ITypedList ), was mich zu der Annahme verleitet, sie an ein Raster zu binden ( oder irgendetwas anderes) wird Reflektion verwenden, um meine Entity-Eigenschaften zu erhalten. Dies scheint eine vergleichsweise teure Operation zu sein, insbesondere wenn der gesamte Code ohnehin generiert wird und die Schnittstellen implementiert werden können.

Hat jemand dazu einen Einblick? Wird die Reflexion verwendet, um den Wert der Eigenschaften zu erhalten / festzulegen? Wenn ja, hat dies einen spürbaren Performance-Effekt, und hat jemand eine Idee, warum sie diesen Weg gegangen sind?

Bearbeiten

Ich konzentriere mich eigentlich darauf, ob ITypedList irgendwo auf dem Weg implementiert wird oder nicht, da dies die Möglichkeit bietet, einen expliziten Mechanismus für die Definition und Interaktion mit Eigenschaften bereitzustellen, ohne auf Reflexion zurückgreifen zu müssen. Während ich kein LINQ to SQL-Projekt hatte, habe ich ein einfaches Entity Framework-Entity-Abfrageergebnis untersucht, und es scheint nicht, ITypedList zu implementieren. Weiß jemand, ob ich nur etwas falsch ansehe, oder wenn nicht, warum ist das der Fall?

Bearbeiten 2

Nachdem ich Marc 'Antwort akzeptiert hatte, dachte ich, es könnte für andere hilfreich sein, wenn ich einen einfachen Code postete, mit dem ich seine Lösung nahtlos implementiert habe. Ich füge folgendes in den statischen Konstruktor für meine Klasse ein:

%Vor%

Obwohl dies für LINQ to SQL gilt, bin ich sicher, dass eine gleichwertige Version für das Entity Framework geschrieben werden könnte. Dadurch wird die Assembly auf Typen mit dem Table -Attribut gescannt und ein benutzerdefinierter Anbieter für jeden von ihnen hinzugefügt.

    
Adam Robinson 20.04.2009, 00:47
quelle

3 Antworten

3

Die Expression-API, die LINQ usw. unterstützt, basiert auf der Reflektion ( MemberInfo ), nicht auf dem Komponentenmodell ( PropertyDescriptor etc) - es gibt also keine große Anforderung für ITypedList . Stattdessen wird der Inhalt von T in IQueryable<T> , IEnumerable<T> und IList<T> usw. abgeleitet.

Der nächstgelegene Wert ist IListSource , aber das ist immer noch nur ein flacher Wrapper um eine richtige typisierte Liste.

Wenn die Leistung der Laufzeitbindung (in PropertyDescriptor ) der Schlüssel ist, sollten Sie sich HyperDescriptor - verwendet Reflection.Emit und TypeDescriptionProvider , um das Komponentenmodell zu umbrechen.

Re das "warum" usw .; Beachten Sie, dass in fast allen Fällen mit LINQ-to-SQL und EF der Expression (oder der "create and set members" -Teil) vor dem Aufruf zu einem Delegaten kompiliert wird - zur Laufzeit gibt es also keine große Reflektion Kosten. Und ebenso wird bei LINQ-to-Objects bereits kompiliert (durch den C # -Compiler).

    
Marc Gravell 20.04.2009, 12:39
quelle
1

Nach meiner Erfahrung mit LINQ to SQL habe ich aus ein paar Gründen festgestellt, dass LINQ Reflektion verwendet, um Feldwerte in Entitätsklasseninstanzen festzulegen und abzurufen. Ich weiß nicht, ob ich mich an all die Gründe erinnern kann, aber hier ist, was ich dir sagen kann.

  1. Wenn ich mich recht erinnere, ruft LINQ keine Eigenschaftsprozeduren auf, sondern setzt und liest alle privaten Feldwerte direkt direkt, was, soweit ich weiß, nur durch Reflektion erfolgen kann.
  2. Die von den MetaData bereitgestellten Namen (in den Attributen für die Eigenschaften der Entitätsklasse) enthalten Informationen zum Feldnamen in Zeichenfolgenform (wenn beispielsweise die Datenbankspalte und der Eigenschaftsname unterschiedlich sind). Sie können daraus schließen, dass LINQ die Reflexion verwenden muss, um das Mitglied nachzusehen, um darauf zuzugreifen.

Ich denke, dass dies dazu dient, Einfachheit zu erzwingen - Sie können sich darauf verlassen, dass die Werte in den Feldern in der Entity-Klasse die Datenbankspaltenwerte direkt widerspiegeln, und es keinen großen Aufwand gibt, das Objekt aus der Datenbank abzurufen (ein neu erstelltes zu füllen) Entität, die den aus der Datenbank abgerufenen Werten entspricht, sollte nicht über Eigenschaftsverfahren geroutet werden). Eine Sache, die ich getan habe, um aufgezählte Werte aus der Datenbank darzustellen, besteht beispielsweise darin, einige der LINQ-generierten Eigenschaften privat zu machen und sie in eine manuell codierte Eigenschaft in einer partiellen Klasse umzuwandeln, die die LINQ-Eigenschaft liest und schreibt. p>     

BlueMonkMN 20.04.2009 12:27
quelle
0

Wenn man sich ansieht, was MSDN bei LINQ to SQL Data Binding zu sagen hat, tut es das scheinen IListSource oder IBindingList zu verwenden.

Übrigens verwendet LINQ Expression Trees , und das ist nicht so viel Reflexion wie Meta- Programmierung. Leistung sollte viel besser als Reflexion sein. Charlie Calvert deckt dies ein wenig in diesem Artikel ab.

    
Erich Mirabal 20.04.2009 02:15
quelle