0
votes

EntityFramework n'inclut pas la clause dans la requête envoyée

J'ai une base de données internationalisée avec permet de dire une table , un i18n table et une traduction tableau.

COLLECTION Le champ Nom contient un GUID à partir de la table I18N Traduction contient une liste des traductions de chaque locale.

voici le code que j'utilise dans c #: xxx

et voici les requêtes SQL générées: xxx

C'est une perte de temps et circulation si j'ai 50 traductions disponibles. Pourquoi ne générant pas: xxx

Qu'est-ce que je manque?

EDIT: J'ai simplifié le code à des fins de cette question. Je sais comme présenté, il serait logique de chercher directement une liste du champ trans_text.

mais "dans le monde réel", chaque traduction aurait au moins deux propriétés ( Texte et image), et chaque objectif aurait d'autres propriétés nécessaires. Donc, il serait toujours nécessaire de faire itérer les collections . Oh, et la traduction existerait toujours.

Ce que je voudrais réaliser, est de récupérer toutes les collections avec la traduction appropriée déjà chargée avec une requête.

Permettez-moi d'ajouter un exemple à illustrer: Une requête SQL de 'vieille style' sans EF serait quelque chose comme: xxx

et code à consommer serait: xxx


0 commentaires

4 Réponses :


1
votes

Essayez de faire la collection comme iquéryable alors il exécutera la requête sur votre serveur, y compris vos filtres ajoutés.

I.e. Avec l'inclusion de

où (x => x.locale_id == "fr"). FirstArdefault ();


3 commentaires

En réalité variable Colls , même si j'avais utilisé var , montrent comme iQuéryable .


Qu'en est-il de traductions dans i18n?


Oh oui c'est une icollection . Devrais-je lancer celui-ci à iquéry ? EDIT: Just Testé, ne peut pas être coulé.



0
votes

La manière incluse

Vous devez utiliser requête () code> ici. p>

chargement des entités associées : p>

appliquer des filtres lors de la chargement explicitement des entités liées forte> p>

La méthode de la requête donne accès à la requête sous-jacente selon laquelle l'entité cadre utilisera lors du chargement des entités liées. Vous pouvez ensuite utiliser LINQ pour appliquer des filtres à la requête avant d'l'exécuter avec un appel à une méthode d'extension LINQ telle que TOLIST, CHARGER, etc. La méthode de la requête peut être utilisée avec les propriétés de la navigation de référence et de la collecte, mais est la plus utile pour les collections où Il peut être utilisé pour ne charger qu'une partie de la collection. Par exemple: p>

var t = ctx.translations.Where(x => x.locale_id == "fr" && i18n_id = ...))
MessageBox.Show(t.trans_text);


1 commentaires

Pourquoi ne peut-il pas faire la collection comme elle-même?



2
votes

Vous énumérez la requête des collections sur la boucle, puis recevez une traduction pour chaque instance. Vous pouvez accomplir la même chose dans une requête.

var ctx = new CollectooEntities();
var dto = ctx.collections.Select(x => new {
        coll_id = x.coll_id,
        coll_price = x.coll_price,
        i18n_defaulttext = x.i18n.i18n_defaulttext,
        trans = x.i18n.translations
            .Where(t => t.locale_id == "fr")
            .Select(t => new { trans_text, trans_picturefilename })
            .FirstOrDefault()
    });

foreach(var c in dto)
{
    MessageBox.Show($"{c.coll_id}, price={c.coll_price}, name is {c.trans?.trans_text ?? c.i18n_defaulttext}, picture file is {c.trans?.trans_picturefilename}");
}


4 commentaires

Merci mais j'ai simplifié pour la question actuelle, chaque traduction aurait 2 propriétés (texte et image), et l'élément de collecte aurait d'autres propriétés que je devrais aborder. Donc, j'aurais besoin de parcourir des collections à travers et d'avoir finalement la traduction nécessaire déjà chargée, est-ce possible?


J'ai projeté juste une propriété, mais vous pouvez projeter toutes les propriétés dont vous avez besoin, à partir d'objets de collecte, d'I18N ou de traduction. Je vois que vous avez modifié la question. Je vais aussi modifier ma réponse.


Merci pour cette solution, mais cela perd le fait que si j'ajoute des champs dans la table, puis synchroniser le modèle EF, je devrai aller manuellement à tous mes lieux de code pour ajouter les nouveaux champs à l'instruction SELECT, car je ' Je ne retourne pas l'objet "collection" lui-même.


Idéalement, vous ne devez lire que ce dont vous avez besoin de la base de données. Si vos exigences changent, la requête serait-elle.



0
votes

Basé sur d'autres réponses, j'ai trouvé une solution qui conserve les objets d'origine dans le résultat de la requête, afin de conserver l'avantage d'obtenir les nouveaux champs disponibles sur la future synchronisation du modèle EF à partir de la base de données:

var ctx = new CollectEntities();

var colls = ctx.collections
    .Select(x => new { Obj = x, x.i18n, trans = x.i18n.translations.Where(t => t.locale_id == "fr").FirstOrDefault() });

foreach (var c in colls2)
{
    MessageBox.Show($"{c.Obj.coll_id}: {c.trans?.trans_text ?? c.Obj.i18n.i18n_default}");
}


0 commentaires