Question

J'ai une requête LINQ mappée avec Entity Framework qui ressemble à ceci:

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

retourne un seul objet d'image et fonctionne comme prévu.

Cependant, cette requête renvoie toutes les propriétés de ma table d'image dans le DB. Dans des circonstances normales, ce serait bien, mais ces images contiennent beaucoup de données binaires qui prend beaucoup de temps pour revenir.

En fait, dans ce état actuel ma requête LINQ fait:

Select ImageId, Name, Data
From Images
...

Mais je besoin d'une requête qui fait cela instread:

Select ImageId, Name
From Images
...

Remarquez que je veux charger tout sauf les données. (Je peux obtenir ces données sur une deuxième passe async)

Était-ce utile?

La solution

Malheureusement, si vous utilisez LINQ to SQL, il n'y a pas de solution optimale.

Vous avez 3 options:

  1. Vous retournez l'entité, avec le suivi du contexte et tout, dans ce cas, l'image, avec tous les champs
  2. Vous choisissez vos champs et retourner un type anonyme
  3. Vous choisissez vos champs et le retour d'une classe personnalisée fortement typé, mais vous perdez suivi, si c'est ce que vous voulez.

I love LINQ to SQL, mais c'est la façon dont il est.

Ma seule solution pour vous serait de restructurer votre DataBase et déplacer toutes les grandes quantités de données dans une table séparée, et un lien vers la table d'images.

De cette façon, lors du retour image que vous ne retournez une clé dans le nouveau champ DataID, et vous pouvez accéder à ces données plus lourdes quand et si vous en avez besoin.

hourras

Autres conseils

Cela va créer une nouvelle image avec uniquement les champs définis. Lorsque vous revenez pour obtenir les données pour les images que vous sélectionnez, je vous suggère d'aller de l'avant et obtenir le plein jeu de données au lieu d'essayer de fusionner avec les id existants / données de nom. Les champs id / nom sont probablement faible par rapport aux données et le code sera beaucoup plus simple que d'essayer de faire la fusion. En outre, il peut ne pas être nécessaire de construire en fait un objet d'image, en utilisant un type anonyme pourrait répondre à vos besoins tout aussi bien.

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();

[Si vous utilisez Linq 2 SQL] Dans le concepteur DBML, il y a une option pour faire des colonnes de table individuels retard chargé. Définir à vrai pour votre grand champ binaire. Ensuite, ces données n'est pas chargé jusqu'à ce qu'il soit effectivement utilisé.

[Question pour vous tous: Est-ce que quelqu'un sait si dans ce MSVS 2010, les cadres d'entités prennent en charge ont retardé chargés varbinary / varchar? ]

Solution # 2 (pour Entity Framework ou LINQ 2 sql):

Créer une vue de la table qui ne comprend que la clé primaire et la varchar (max) / varbinary (max). Carte que dans EF.

Dans votre concepteur Entity Framework, supprimez le varbinary (max) / varchar (max) propriété de la définition de la table (laissant définie uniquement dans la vue). Cela devrait exclure le champ des opérations de lecture / écriture à cette table, si vous pouvez vérifier que avec l'enregistreur.

En général, vous aurez accès aux données via la table qui exclut le blob de données. Lorsque vous avez besoin du blob, vous chargez une ligne de la vue. Je ne sais pas si vous serez en mesure d'écrire à la vue, je ne sais pas comment vous feriez écrit. Vous pouvez être en mesure d'écrire à la vue, ou vous devrez peut-être écrire une procédure stockée, ou vous pouvez le buste d'un fichier DBML pour une table.

Vous ne pouvez pas le faire avec LINQ au moins pour l'instant ...

La meilleure approche que je sais est de créer View pour la table dont vous avez besoin sans grands champs et utilisez LINQ avec cette View.

Sinon, vous pouvez utiliser la nouvelle sélection dans l'expression de requête ...

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

Les expressions de requête LINQ sont converties en fait l'expression Lambda au moment de la compilation, mais je Prefair en utilisant l'expression de requête généralement parce que je trouve plus lisible et compréhensible.

Merci :)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top