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.
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).
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.
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>
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.
Tags und Links c# entity-framework reflection linq-to-sql vb.net