Piszę system ASP.net oparty na tagach. Stosując następujący schemat DB:LINQ options.loadwith problem
Topic <many-many> TagTopicMap <many-many> Tag
Zasadniczo jest to podejście 3NF (Toxi) które znalazłem z następujących opcji: http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html
Oto fragment kodu mam:
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);
Po wykonaniu tego, wynik jest w porządku, ale pojawia się 11 pojedynczych zapytań SQL, jeden dla uzyskania listy 10 najważniejszych tematów:
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
I 10 z nich innych w celu uzyskania szczegółowych informacji o tagach pojedynczo.
próbowałem zamienić dwa oświadczenia loadwith i wyłączać, a okazało się, że następujące konsekwencje:
loadwith<topic> : no difference for on or off.
loadwith<tagtopicmap>: 11 Queries when on, much more when off.
W skrócie tylko druga opcja loadwith działa zgodnie z oczekiwaniami. Pierwszy nie ma żadnego efektu!
Próbowałem również utworzyć zestaw wyników ToList(). Ale pojawia się jeszcze więcej problemów: w przypadku części szczegółów tagów, pobiera ona tylko te UNIKALNE pozycje, wszystkie te powtarzające się znaczniki (ten sam tag może pojawić się w wielu tematach, oczywiście!) Są odrzucane przez zapytanie.
Ostatnią rzeczą, w następującym kodzie użyłem w aspx do pobierania danych, w przypadku dokonywania ToList wynik(), I zmiana (IQueryable) do (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>
<%
}
%>
Nie zawsze INNER DOŁĄCZ. Jeśli * wszystkie pola łączenia będą miały wartość null *, wówczas będzie to LEFT JOIN - jest to prawdopodobnie nieudokumentowana "nieprawidłowa funkcja", którą INNER JOIN generuje, nawet jeśli pola łączenia * zawierają niektóre (ale nie wszystkie) null-stanie kolumny *. –