LINQ options.loadwith问题

xan*_*ndy 8 c# linq 3nf linq-to-sql

我正在编写一个基于标签的ASP.net系统.使用以下db方案:

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);
Run Code Online (Sandbox Code Playgroud)

当我执行它时,结果很好,但它提供了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 
Run Code Online (Sandbox Code Playgroud)

其他10个用于单独获取标签的详细信息.

我试图打开和关闭两个loadwith语句,发现以下情况发生:

loadwith<topic> : no difference for on or off.
loadwith<tagtopicmap>: 11 Queries when on, much more when off.
Run Code Online (Sandbox Code Playgroud)

简而言之,只有第二个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>
    <%
        }
    %>
Run Code Online (Sandbox Code Playgroud)

Mar*_*ark 5

简短的回答是:LinqToSql有这样的几个怪癖,有时你必须使用解决方法......

Linq2Sql LoadWith选项只会导致数据库表之间的内部联接,因此您可以通过将Linq语句重写为类似的方式强制执行类似的行为(请原谅任何拼写错误,我习惯用VB语法编写Linq ...):

var x = from topic in db.Topics
        join topicMap in topic.TagTopicMaps
        orderby topic.dateAdded descending
        group topicMap by topicMap.topic into tags = Group;
Run Code Online (Sandbox Code Playgroud)

这种语法可能是非常错误的,但基本的想法是你强迫Linq2Sql评估Topics和TagTopicMaps之间的连接,然后使用分组(或"group join","let"等)来保留对象的层次结构.结果集.