Frage

Ich habe eine LINQ-Abfrage mit dem Framework-Entity zugeordnet, die etwa wie folgt aussieht:

image = this.Context.ImageSet
                    .Where(n => n.ImageId == imageId)
                    .Where(n => n.Albums.IsPublic == true)
                    .Single();

Das gibt ein einzelnes Bildobjekt und arbeitet wie vorgesehen.

Allerdings ist diese Abfrage liefert alle Eigenschaften meiner Bild-Tabelle in der DB. Unter normalen Umständen wäre dies in Ordnung sein, aber diese Bilder eine Menge von binären Daten enthalten, die eine sehr lange Zeit zurück nimmt.

Im Grunde genommen darin aktuellen Zustand meiner Linq-Abfrage tut:

Select ImageId, Name, Data
From Images
...

Aber ich brauche eine Abfrage, die diese instread tut:

Select ImageId, Name
From Images
...

Beachten Sie i alles außer den Daten laden möge. (Ich kann diese Daten auf einem zweiten Asynchron-Pass erhalten)

War es hilfreich?

Lösung

Leider, wenn mithilfe von LINQ to SQL, gibt es keine optimale Lösung.

Sie haben 3 Optionen:

  1. Sie kehren die Entity, mit Context Tracking und alle, in diesem Fall Bild, mit allen Bereichen
  2. Sie wählen Ihre Felder und zurück einen anonymen Typ
  3. Sie wählen Ihre Felder und zurück eine stark typisierte benutzerdefinierte Klasse, aber Sie verlieren Tracking, wenn das ist, was Sie wollen.

Ich liebe LINQ to SQL, aber das ist so, wie es ist.

Meine einzige Lösung für Sie Ihre Datenbank zu restrukturieren wäre, und alle großen Daten in eine separate Tabelle verschieben, und Link, um es aus dem Bild Tabelle.

Auf diese Weise, wenn die Bild Rückkehr Sie würden nur einen Schlüssel in dem neuen Daten-ID-Feld zurückzukehren, und dann könnten Sie diese schwereren Daten zugreifen, wenn und wenn Sie es benötigt wird.

cheers

Andere Tipps

Dies wird ein neues Bild mit nur diesen Feldern eingestellt erstellen. Wenn Sie gehen zurück, um die Daten für die Bilder bekommen Sie wählen, würde ich den vollständigen Datensatz gehen voran und immer vorschlagen, anstatt zu versuchen, es mit den vorhandenen id / name Daten zu fusionieren. Die id / name Felder sind vermutlich klein im Verhältnis zu den Daten und der Code wird viel einfacher als zu versuchen, die Zusammenführung zu tun. Auch kann es nicht erforderlich sein, um tatsächlich ein Bildobjekt zu konstruieren, einen anonymen Typen verwenden könnte Ihre Zwecke genauso gut passen.

image = this.Context.ImageSet
                    .Where(n => n.ImageId == imageId)
                    .Where(n => n.Albums.IsPublic == true)
                    .Select( n => new Image { ImageId = n.ImageId, Name = n.Name }
                    .Single();

Im DBML Designer [Wenn Linq 2 SQL verwenden], gibt es eine Option einzelne Tabellenspalten machen verzögerungs geladen. Setzen Sie dies auf true für Ihr großes binäres Feld. Dann wird, dass die Daten nicht geladen, bis es tatsächlich verwendet wird.

[Frage für Sie alle: Wer weiß, ob die ADO.NET Entity Framework varbinary / varchar die in MSVS 2010 geladen verzögert unterstützen? ]

Lösung # 2 (für Entity Framework oder Linq 2 SQL):

Erstellen Sie eine Ansicht der Tabelle, die nur den Primärschlüssel und die varchar (max) / varbinary (max) umfasst. Karte, die in EF.

Innerhalb Ihres Entity Framework Designer, löschen Sie die varbinary (max) / varchar (max) Eigenschaft aus der Tabellendefinition (so dass es nur in der Ansicht definiert). Dies sollte das Feld von Lese- / Schreiboperationen auf diese Tabelle ausschließen, wenn Sie, dass mit dem Logger überprüfen könnten.

Im Allgemeinen werden die Daten durch die Tabelle zugreifen, die Datenblob ausschließt. Wenn Sie den Blob benötigen, laden Sie eine Zeile aus der Ansicht. Ich bin mir nicht sicher, ob Sie der Ansicht schreiben werden in der Lage, ich bin nicht sicher, wie man schreibt tun würde. Sie können zu der Ansicht schreiben können, oder Sie können eine gespeicherte Prozedur schreiben müssen, oder Sie können eine DBML-Datei für die eine Tabelle Büste aus.

Sie können es nicht mit LINQ zumindest für jetzt ...

Der beste Ansatz, den ich weiß, ist, erstellen View für die Tabelle, die Sie ohne große Felder benötigen und verwenden LINQ mit dieser View.

Alternativ können Sie die Auswahl neu in der Abfrage-Ausdruck verwenden ...

var image =
(
    from i in db.ImageSet
    where i.ImageId == imageId && i.Albums.IsPublic
    select new
    {
        ImageId = i.ImageId,
        Name = i.Name
    }
).Single()

Die LINQ-Abfrage Ausdrücke tatsächlich auf den Lambda-Ausdruck bei der Kompilierung konvertiert werden, aber ich PreFair mit dem Abfrage-Ausdruck im Allgemeinen, weil ich es besser lesbar und verständlich finden.

Danke :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top