2016-07-01 4 views
1

Wenn ich ein Objekt A mit vielen Eigenschaften habe, von denen ich nur ein Paar brauche, kann ich die Leistung steigern, indem ich keine unnötigen Daten übertrage, dh nur die Objekteigenschaften auswähle ein neuer Typ B, entweder benannt oder anonym.LINQ: Wählen Sie bestimmte Objekteigenschaften In dasselbe Objekt

Stellen Sie sich nun vor, ich möchte eine Liste dieser ursprünglichen Objekte A an eine datagridview binden, die nur die paar Eigenschaften anzeigt, die ich möchte. Ich habe die datagridview-Spalten mit den Eigenschaftsnamen des ursprünglichen Objekts A erstellt und seinen Datenquellentyp auf typeof (A) festgelegt. Ich habe mich gefragt, ob ich in das gleiche Objekt A auswählen kann nur die Eigenschaften Weglassen brauche ich nicht, das heißt

public class MyObject 
{ 
    public string prop1 { get; set; } 
    public string prop2 { get; set; } 
    ..... 
    public string propN { get; set; } 
} 

var list = context.MyObject 
     .Select(n => new MyObject { prop1 = n.prop1, prop2 = n.prop2 }).ToList(); 

Auf diese Weise brauche ich nicht eine neue Art zu definieren, entweder den Namen oder anonym. Die Frage ist, bekomme ich etwas in der Leistung, oder ich habe immer noch den Overhead des ursprünglichen großen Objekts A Informationen, obwohl ich Daten nicht für alle seine Eigenschaften übertrage.

Alex

+0

Vielen Dank für Ihre Antworten. –

Antwort

1

Der einzige sinnvolle Leistungszuwachs, vorausgesetzt Ihr Konstruktor ist "billig", liegt im SQL- und Datentransport von/nach.

Das heißt, es geht nicht alles um Leistung. Manchmal geht es um Klarheit, Erweiterbarkeit, Entkopplung usw. Clarity-weise zwingen Sie andere dazu, sich die Frage stellen zu müssen: "Wird diese Eigenschaft von der Benutzeroberfläche verwendet?"

Zusätzlich zu den Problemen mit der Übersichtlichkeit haben Sie eine Kopplung zwischen der Benutzeroberfläche und den Back-End-Entitäten. Das ist nicht ideal. Eine billige/temporäre Lösung könnte einfach eine solche sein. Bedenken Sie, dass es aufgrund der Schnittstelle in der Klasse immer noch gekoppelt ist, aber es wäre etwas, das sich in Zukunft auf Wunsch einfach anpassen lässt.

public interface IMyModel 
{ 
    string prop1 { get; set; } 
    string prop2 { get; set; } 
} 

public class MyObject : IMyModel 
{ 
    public string prop1 { get; set; } 
    public string prop2 { get; set; } 
    ..... 
    public string propN { get; set; } 
} 

IEnumerable<IMyModel> list = context.MyObject 
    .Select(n => new { n.prop1, n.prop2 }) // only select these properties 
    .ToArray() // execute the query 
    .Select(n => (IMyModel)new MyObject { prop1 = n.prop1, prop2 = n.prop2 }); // construct our desired object 
+0

Ich vermute, dass diese Frage von meiner Unwissenheit über die Entkopplung von UI von meinem Backend herrührt. Wenn meine Entitäten in meinem Backend definiert sind und ich eine Art "dto" -Objekte in meiner UI anzeigen muss, wo sollen diese definiert werden (so etwas wie das IMyModel deiner Antwort ???)? Ich nehme an, dass sowohl meine Benutzeroberfläche als auch mein Back-End über sie wissen sollten, also müsste ich sie in einer dritten Ebene zwischen den beiden definieren? –

+0

Wenn wir davon ausgehen, dass Sie eine Assembly für den gesamten Benutzeroberflächencode haben, eine separate Assembly, die Ihren Datenzugriff und Entitäten enthält, können IMyModel und alle implementierten Elemente in der Benutzeroberflächenassembly (oder einer Assembly, auf die nur von der Benutzeroberflächenassembly verwiesen wird) enthalten sein. Irgendwo müssen Sie von Ihrem Datenobjekt zu Ihrem UI-Objekt mappen, und wo immer dies geschieht, muss Ihr Code über beides wissen. –

3

Eigentlich, denke ich, kann die Leistung nicht viel verbessern, wie Select-Anweisung durch all Ihre Liste gehen und eine neue Liste von Objekten für Sie erstellen. Aber wenn Sie eine Referenzeigenschaft haben, die Sie nicht verwenden. Sie können dort speichern.

Wenn es keine komplizierte Logik gibt, wenn Sie Daten zur UI zeigen. Molke, behalt das Modell nicht so wie es ist.

+0

Einige Objekte haben Referenzeigenschaften und andere nicht, aber sie könnten eine große Zeichenfolgeneigenschaft haben, die ich in meiner Datagridview nicht anzeigen muss. –

2

Wenn dies nur für die UI-Anzeige gilt, gibt es keine Leistungssteigerung. Egal zu welcher Zeit Sie gewinnen, Sie verlieren, indem Sie eine neue Liste anonymer Typen erstellen.

Wenn Sie jedoch dieses Objekt über das Netzwerk senden möchten (z. B. als Antwort auf eine Anforderung), ist dies sinnvoll. Auf diese Weise müssen weniger Eigenschaften serialisiert und über das Netzwerk gesendet werden.

In den meisten Fällen sollten Sie sich jedoch mit der Leistung auf dieser Ebene sorgen. Der Benutzer wird eine Verbesserung auf einem solchen Niveau nicht bemerken. Wenn Sie die Leistung Ihrer Anwendung wirklich verbessern möchten, sollten Sie sie profilieren und die Hotspots finden.

+0

Ja, ich sollte anfangen, ein Profiling zu verwenden, das ich noch nicht gemacht habe, das mir eine echte Antwort geben wird. –

Verwandte Themen