28 votes

Entity Framework - obtenir uniquement des colonnes spécifiques

Puis-je faire mon EF objets ne récupérer que des colonnes spécifiques dans le sql exécuté? Si je suis l'exécution du code ci-dessous pour récupérer les objets, il y a une chose que je peux faire pour ne recevoir que certaines colonnes si l'on voulait?

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

Cela permettrait de générer une clause select qui contient toutes les colonnes. Mais, si j'ai une colonne qui contient une grande quantité de données qui ralentit vraiment la requête, comment puis-je avoir mes objets à exclure que la colonne du sql généré?

Si ma table a Id(int), le Statut(int), les Données(blob), comment puis-je faire ma requête sera

select Id, Status from TableName

au lieu de

select Id, Status, Data from TableName

La proposition 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 vais appeler ça comme

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

Cependant, j'ai une erreur de compilation: Impossible de convertir implicitement le type 'AnonymousType#1" à " des Entités.BatchRequest'

38voto

Craig Stuntz Points 95965

Assurez-vous. 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 DB a différentes tables que le vôtre). J'ai ajouté mon modèle EF de LINQPad et tapé la requête suivante:

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

LINQPad m'indique que le code 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 sont inclus.

Répondre aux questions à jour

Votre columns argument dit il faut un type T et retourne le même type. Par conséquent, l'expression que vous avez pass doit se conformer à la présente, ou vous avez besoin de 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 de soins à utiliser.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X