41 Stimmen

Nur bestimmte Spalten erhalten

Kann ich meine EF-Objekte nur bestimmte Spalten in der ausgeführten SQL abrufen lassen? Wenn ich den unten stehenden Code ausführe, um Objekte abzurufen, gibt es etwas, das ich tun kann, um nur bestimmte Spalten abzurufen, falls gewünscht?

public IEnumerable<T> GetBy(Expression<Func<T, bool>> exp)
{
    return _ctx.CreateQuery<T>(typeof(T).Name).Where<T>(exp);
}

Dies würde eine Select-Klausel erzeugen, die alle Spalten enthält. Aber wenn ich eine Spalte habe, die eine große Menge an Daten enthält, die die Abfrage wirklich verlangsamt, wie kann ich dann meine Objekte dazu bringen, diese Spalte aus der generierten SQL auszuschließen?

Wenn meine Tabelle Id(int), Status(int), Data(blob) hat, wie kann ich meine Abfrage machen werden

select Id, Status from TableName

anstelle von

select Id, Status, Data from TableName

Ausgehend von dem nachstehenden Vorschlag lautet meine Methode

public IEnumerable<T> GetBy(Expression<Func<T, bool>> exp, Expression<Func<T, T>> columns)
{
    return Table.Where<T>(exp).Select<T, T>(columns);
}

Und ich nenne es so

mgr.GetBy(f => f.Id < 10000, n => new {n.Id, n.Status});

Ich erhalte jedoch einen Kompilierfehler:

Der Typ 'AnonymousType#1' kann nicht implizit in 'Entities.BatchRequest' umgewandelt werden.

55voto

Craig Stuntz Punkte 124703

Sicher, das macht die Projektion:

var q = from r in Context.TableName
        select new 
        {
            Id = r.Id,
            Status = r.Status
        }

Hier ist ein aktuelles Beispiel (natürlich hat meine DB andere Tabellen als Ihre). Ich fügte mein EF-Modell zu LINQPad hinzu und gab die folgende Abfrage ein:

from at in AddressTypes
select new
{
    Id = at.Id,
    Code = at.Code
}

LINQPad zeigt mir, dass die generierte SQL ist:

SELECT 
    1 AS [C1], 
    [Extent1].[AddressTypeId] AS [AddressTypeId], 
    [Extent1].[Code] AS [Code]
FROM 
    [dbo].[AddressType] AS [Extent1]

Alle anderen Felder der Tabelle werden nicht berücksichtigt.

Beantwortung der aktualisierten Frage

Ihr columns sagt, dass es einen Typ T annimmt und denselben Typ zurückgibt. Daher muss der Ausdruck, den Sie übergeben, dem entsprechen, oder Sie müssen den Typ des Arguments ändern, d.h.:

public IEnumerable<U> GetBy<U>(Expression<Func<T, bool>> exp, Expression<Func<T, U>> columns)
{
    return Table.Where<T>(exp).Select<T, U>(columns);
}

Jetzt kann der Ausdruck jeden beliebigen Typ zurückgeben.

0 Stimmen

Ich möchte dies in einer generischen Art und Weise tun, so dass ich einfach ein weiteres Argument zum GetBy-Methodenaufruf hinzufügen kann, bei dem es sich um die Spalten handelt, die zurückgegeben werden sollen.

0 Stimmen

Sie müssen also einen Select-Ausdruck zusammen mit Ihrem Where-Ausdruck übergeben, d. h.: var foo = GetBy(r => r.Id == someId, r => new { r.Id, R.Status });

0 Stimmen

Ich habe meinen Beitrag oben mit weiteren Informationen ergänzt

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X