Question

Je suis en train d'écrire un système ASP.net basée sur des balises. En utilisant le schéma db suivant:

Topic <many-many> TagTopicMap <many-many> Tag

Fondamentalement, il est une approche 3NF (toxi) que je trouve de ce qui suit: http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html

Voici l'extrait de code que j'ai:

DataLoadOptions options = new DataLoadOptions();
        options.LoadWith<Topic>(t => t.TagTopicMaps);
        options.LoadWith<TagTopicMap>(tt => tt.Tag);
        var db = new lcDbDataContext();
        db.LoadOptions = options;
        db.Log = w;

        var x = from topic in db.Topics
                orderby topic.dateAdded descending
                select topic;

        ViewData["TopicList"] = x.Take(10);

Quand j'exécute cela, le résultat est bien, mais il arrive avec 11 simples requêtes SQL, un pour obtenir la liste des 10 premiers sujets:

    SELECT TOP (10) [t0].[Id], [t0].[title], [t0].[dateAdded]
FROM [dbo].[Topics] AS [t0] ORDER BY [t0].[dateAdded] DESC
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1 

Et 10 ceux d'autres pour obtenir des détails sur les étiquettes individuellement.

J'ai essayé de changer les deux déclarations de LoadWith sur et en dehors, et nous avons constaté les choses suivantes vont se passer:

loadwith<topic> : no difference for on or off.
loadwith<tagtopicmap>: 11 Queries when on, much more when off.

En bref, seule la deuxième option LoadWith fonctionne comme prévu. Le premier n'a pas d'effet!

J'ai essayé aussi de faire la ToList resultset (). Mais encore plus problème en sortant:. Pour les balises en détail une partie, il récupérer uniquement les objets uniques, toutes ces balises répétition (! Cette même étiquette peut apparaître dans un certain nombre de sujet, bien sûr) sont abandonnées par la requête

Une dernière chose, suivant le code que j'utilisé dans ASPX pour récupérer les données, en cas de rendre le résultat tolist (), je change (IQueryable) à (IList):

<% foreach (var t in (IQueryable)ViewData["TopicList"])
       {
           var topic = (Topic)t;

    %>
    <li>
        <%=topic.title %> || 
        <% foreach (var tt in (topic.TagTopicMaps))
           { %>
                <%=tt.Tag.Name%>, 
                <%} %>
    </li>
    <%
        }
    %>
Était-ce utile?

La solution

La réponse courte est: LinqToSql a plusieurs bizarreries comme celui-ci, et parfois vous devez utiliser le travail contournements ...

L'option Linq2Sql LoadWith provoque simplement une jointure entre les tables de base de données, vous pouvez forcer un comportement similaire par Réécrire votre déclaration Linq à quelque chose comme (s'il vous plaît pardonnez les fautes de frappe, je suis habitué à la syntaxe LINQ writting VB ... ):

var x = from topic in db.Topics
        join topicMap in topic.TagTopicMaps
        orderby topic.dateAdded descending
        group topicMap by topicMap.topic into tags = Group;

Cette syntaxe peut être horriblement mal, mais l'idée de base est que vous forcer Linq2Sql d'évaluer la jonction entre les thèmes et TagTopicMaps, puis utilisez le regroupement (ou « groupe rejoindre », « laisser », etc.) pour préserver l'objet heirarchy dans le jeu de résultats.

Autres conseils

Régler la EnabledDefferedLoad sur votre classe DataContext false.

Le problème dans votre cas est de prendre (10). Voici de la bouche du cheval:

https://connect.microsoft.com/VisualStudio/feedback/details/473333/linq-to-sql-loadoptions-ignored-when-using-take-in-the-query

La solution proposée consiste à ajouter Skip (0). Cela ne fonctionne pas pour moi, mais SKIP (1) a fait le travail. Inutile comme il peut être, au moins je sais où mon problème.

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