Domanda

Sto scrivendo un sistema di ASP.net basato su tag. Utilizzando il seguente schema db:

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

In sostanza si tratta di un approccio 3NF (toxi) che ho trovato tra i seguenti: http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html

Ecco il frammento di codice che ho:

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

Quando eseguo questo, il risultato va bene, ma si tratta con 11 query SQL singoli, uno per ottenere l'elenco dei primi 10 argomenti:

    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 

E 10 di quelle altre per ottenere i dettagli dei tag singolarmente.

Ho cercato di cambiare le due affermazioni loadwith e fuori, e abbiamo trovato le seguenti cose accadono:

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

In breve, solo la seconda opzione loadwith funziona come previsto. La prima non ha alcun effetto!

Inoltre ho provato a fare il ToList di risultati (). Ma ancora più problemi in uscita:. Per la parte tag dettaglio, è recuperare solo gli elementi UNICHE, tutte quelle modifiche che si ripetono (! Lo stesso tag potrebbero apparire in un certo numero di argomento, ovviamente) sono sceso dalla query

Un ultima cosa, segue è il codice che ho usato in aspx per recuperare i dati, in caso di rendere il ToList risultato (), cambio (IQueryable) a (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>
    <%
        }
    %>
È stato utile?

Soluzione

La risposta breve è: LinqToSql ha diverse peculiarità di questo tipo, e, talvolta, è necessario utilizzare il lavoro-around ...

L'opzione Linq2Sql LoadWith provoca semplicemente un inner join tra le tabelle del database, in modo da poter forzare un comportamento simile da rewritting vostra dichiarazione Linq a qualcosa di simile (ti prego di perdonare eventuali errori di battitura, io sono abituato a scrittura Linq nella sintassi 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;

Questa sintassi può essere terribilmente sbagliato, ma l'idea di base è che si forza Linq2Sql per valutare l'unione tra argomenti e TagTopicMaps, e quindi utilizzare il raggruppamento (o "gruppo di join", "lascia", ecc) per conservare l'oggetto gerarchia nel set di risultati.

Altri suggerimenti

Imposta l'EnabledDefferedLoad sulla tua classe DataContext false.

Il problema nel tuo caso è prendere (10). Ecco dalla bocca del cavallo:

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

La soluzione suggerita è quella di aggiungere Skip (0). Che non ha funzionato per me, ma Skip (1) ha funzionato. Inutile come può essere, almeno so dove il mio problema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top