Obtenir uniquement des colonnes spécifiques

entity-framework

Question

Puis-je faire en sorte que mes objets EF ne récupèrent que des colonnes spécifiques du SQL exécuté? Si j'exécute le code ci-dessous pour récupérer des objets, puis-je faire quelque chose pour obtenir uniquement certaines colonnes si nécessaire?

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

Cela générerait une clause select contenant toutes les colonnes. Mais si ma colonne contient une grande quantité de données qui ralentit réellement la requête, comment mes objets peuvent-ils exclure cette colonne de la liste SQL générée?

Si ma table a Id (int), Status (int), Data (blob), comment puis-je faire ma requête

select Id, Status from TableName

au lieu de

select Id, Status, Data from TableName

De la suggestion ci-dessous, ma méthode est

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

Et je l'appelle comme si

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

Cependant, je reçois une erreur de compilation:

Impossible de convertir implicitement le type 'AnonymousType # 1' en 'Entities.BatchRequest'

Réponse acceptée

Sûr. La projection fait ceci:

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

Voici un exemple réel (évidemment, ma base de données a des tables différentes des vôtres). J'ai ajouté mon modèle EF à LINQPad et tapé la requête suivante:

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

LINQPad me montre que le SQL généré est:

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

Aucun des autres champs de la table n'est inclus.

Répondre à la question mise à jour

Votre argument de columns indique qu'il faut un type T et retourne le même type. Par conséquent, l'expression que vous passez doit être conforme à celle-ci, ou vous devez changer le type de l'argument, c'est-à-dire:

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

Maintenant, l'expression peut renvoyer n'importe quel type que vous souhaitez utiliser.



Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow