Варианты по LINQ.проблема loadwith так
Я пишу тег-системы ASP.NET . Используя следующую схему БД:
Topic <many-many> TagTopicMap <many-many> Tag
в основном это подход 3NF (toxi), который я нашел из следующего: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 работает так, как ожидалось. Первый не имеет никакого эффекта!
Я также попытался сделать resultset 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>
<%
}
%>
3 ответов
короткий ответ: LinqToSql имеет несколько таких причуд, и иногда вам приходится использовать обходные пути...
опция Linq2Sql LoadWith просто вызывает внутреннее соединение между таблицами базы данных, поэтому вы можете заставить подобное поведение, переписав свой оператор Linq на что-то вроде (Пожалуйста, простите любые опечатки, я привык писать Linq в синтаксисе 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;
этот синтаксис может быть ужасно неправильно, но основная идея заключается в том, что вы заставляете Linq2Sql оценить соединение между темами и TagTopicMaps, а затем используйте группировку (или "group join", " let " и т. д.) сохранить объект heirarchy в результирующем наборе.
проблема в вашем случае-Take (10). Вот из лошадиных уст:--1-->
предлагаемым обходным путем является добавление Skip (0). Это не сработало для меня, но Skip(1) действительно работал. Как бы бесполезно это ни было, по крайней мере, я знаю, в чем моя проблема.