LINQ options.loadwith 问题

发布于 2024-07-21 03:02:39 字数 1931 浏览 7 评论 0 原文

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

主题 TagTopicMap <多对多> 基本上

,这是我从以下内容中找到的 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 选项按预期工作。 第一个没有任何效果!

我还尝试将结果集设为ToList()。 但更多的问题出现了:对于标签详细信息部分,它只检索那些唯一的项目,所有这些重复标签(当然,相同的标签可能出现在多个主题中!)都会被查询删除。

最后一件事,以下是我在 aspx 中用于检索数据的代码,为了使结果为 list(),我将 (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>
    <%
        }
    %>

I am writing a tag-based ASP.net system. Using the following db scheme:

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

Basically it is a 3NF approach (toxi) that I found from the following: http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html

Here is the code snippet I have:

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

When I execute this, the result is fine, but it comes up with 11 single SQL queries, one for getting the list of top 10 topics:

    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 

And 10 of those other for getting details of the tags individually.

I tried to switch the two loadwith statements on and off, and found the following things happen:

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

In short, ONLY the second loadwith option is working as expected. The first one doesn't have any effect!

I also tried to make the resultset ToList(). But even more problem coming out: for the tags detail part, it only retrieve those UNIQUE items, all those repeating tags (that same tag might appear in a number of topic, of course!) are dropped by the query.

One last thing, following is the code I used in aspx to retrieve the data, in case of making the result tolist(), I change (IQueryable) to (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>
    <%
        }
    %>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迎风吟唱 2024-07-28 03:02:39

简短的答案是: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;

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

The short answer is: LinqToSql has several quirks like this, and sometimes you have to use work-arounds...

The Linq2Sql LoadWith option simply causes an inner join between the database tables, so you can force similar behavior by rewritting your Linq statement to something like (please forgive any typos, I'm used to writting Linq in VB syntax...):

var x = from topic in db.Topics
        join topicMap in topic.TagTopicMaps
        orderby topic.dateAdded descending
        group topicMap by topicMap.topic into tags = Group;

This syntax may be horribly wrong, but the basic idea is that you force Linq2Sql to evaluate the join between Topics and TagTopicMaps, and then use grouping (or "group join", "let", etc.) to preserve the object heirarchy in the result set.

祁梦 2024-07-28 03:02:39

将数据上下文类上的 EnabledDefferedLoad 设置为 false。

Set the EnabledDefferedLoad on your datacontext class to false.

唠甜嗑 2024-07-28 03:02:39

您的情况的问题是 Take(10)。 以下来自马口:

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

建议的解决方法是添加 Skip(0)。 这对我不起作用,但 Skip(1) 确实有效。 虽然可能没什么用,但至少我知道我的问题出在哪里。

The problem in your case is Take(10). Here's from the horse's mouth:

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

The suggested workaround is to add Skip(0). That did not work for me, but Skip(1) did work. Useless as it may be, at least I know where my problem is.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文