8

タグベースの 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);

これを実行すると、結果は問題ありませんが、上位 10 のトピックのリストを取得するための 11 の単一 SQL クエリが表示されます。

    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個。

2 つの loadwith ステートメントのオンとオフを切り替えようとしたところ、次のことがわかりました。

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

つまり、2 番目の loadwith オプションのみが期待どおりに機能します。最初のものは効果がありません!

また、結果セットの ToList() を作成しようとしました。しかし、さらに問題が発生します。タグの詳細部分については、これらの UNIQUE アイテムのみを取得し、すべての繰り返しタグ (もちろん、同じタグが多くのトピックに表示される可能性があります!) はクエリによって削除されます。

最後に、データを取得するために 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>
    <%
        }
    %>
4

3 に答える 3

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;

この構文はひどく間違っている可能性がありますが、基本的な考え方は、Linq2Sql にトピックと TagTopicMap 間の結合を強制的に評価させ、グループ化 (または「グループ結合」、「let」など) を使用してオブジェクト階層を保持することです。結果セット。

于 2009-05-23T20:17:19.497 に答える
1

datacontextクラスのEnabledDefferedLoadをfalseに設定します。

于 2009-11-29T05:17:41.400 に答える
0

あなたの場合の問題は 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) はうまくいきました。役に立たないかもしれませんが、少なくとも私は自分の問題がどこにあるかを知っています。

于 2012-02-06T17:01:45.073 に答える