J'ai une base de données internationalisée avec permet de dire une table code> code>, un voici le code que j'utilise dans c #: p> et voici les requêtes SQL générées: p> C'est une perte de temps et circulation si j'ai 50 traductions disponibles. Pourquoi ne générant pas: p> Qu'est-ce que je manque? P> 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. P> mais "dans le monde réel", chaque 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. P> Permettez-moi d'ajouter un exemple à illustrer:
Une requête SQL de 'vieille style' sans EF serait quelque chose comme: p> et code à consommer serait: p> i18n code> table et une traduction
code> tableau.
COLLECTION CODE> Le champ Nom contient un GUID à partir de la table CODE> I18N
Traduction CODE> contient une liste des traductions de chaque locale. P>
traduction code> aurait au moins deux propriétés ( Texte et image), et chaque objectif code> code> aurait d'autres propriétés nécessaires. Donc, il serait toujours nécessaire de faire itérer les collections
code>. Oh, et la traduction existerait toujours. P>
4 Réponses :
Essayez de faire la collection comme I.e. Avec l'inclusion de p>
iquéryable code> alors il exécutera la requête sur votre serveur, y compris vos filtres ajoutés. P>
où (x => x.locale_id == "fr"). FirstArdefault (); Code> P>
En réalité variable Colls code>, même si j'avais utilisé
var code>, montrent comme iQuéryable
Qu'en est-il de traductions code> dans i18n?
Oh oui c'est une icollection
Vous devez utiliser 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>
requête () code> ici. p>
var t = ctx.translations.Where(x => x.locale_id == "fr" && i18n_id = ...))
MessageBox.Show(t.trans_text);
Pourquoi ne peut-il pas faire la collection comme elle-même?
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}"); }
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.
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}"); }