Я пишу систему ASP.net на основе тегов. Используя следующую схему БД:
Topic <many-many> TagTopicMap <many-many> Tag
В основном это 3NF-подход (токси), который я нашел из следующего: http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html
Вот фрагмент кода, который у меня есть:
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);
Когда я выполню это, результат будет хорошим, но он получит 11 отдельных SQL-запросов, один для получения списка из 10 лучших тем:
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
И 10 других для получения подробной информации о тегах.
Я попытался включить и выключить два оператора loadwith и обнаружил следующее:
loadwith<topic> : no difference for on or off.
loadwith<tagtopicmap>: 11 Queries when on, much more when off.
Короче говоря, ТОЛЬКО вторая опция loadwith работает как положено. Первый не имеет никакого эффекта!
Я также пытался сделать результирующий набор ToList (). Но возникает еще больше проблем: для части с подробной информацией о тегах он извлекает только те УНИКАЛЬНЫЕ элементы, все эти повторяющиеся теги (этот же тег может появляться в ряде тем, разумеется!) Отбрасываются запросом.
И последнее, что следует за кодом, который я использовал в aspx для извлечения данных. В случае использования результата tolist () я изменяю (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>
<%
}
%>