LinqToSQL查询loadwith性能

时间:2010-11-17 18:42:34

标签: c# linq-to-sql

我发现this link解释了我的问题并得到了答案,但似乎无法使其发挥作用。

以下是我对DataLoadOptions的看法:

        options.LoadWith<Support>(p => p.PostBase);
        options.LoadWith<Support>(p => p.PostMaterial);
        options.LoadWith<Support>(p => p.PostPosition);
        options.LoadWith<Support>(p => p.PostSize);
        options.LoadWith<Support>(p => p.PostType);
        options.LoadWith<Support>(p => p.Signs);
        options.LoadWith<Support>(p => p.SupportComments);
        options.LoadWith<Support>(p => p.SupportInspections);
        options.LoadWith<Support>(p => p.SupportPhotos);
        options.LoadWith<Sign>(p => p.SignBacking);
        options.LoadWith<Sign>(p => p.SignComments);
        options.LoadWith<Sign>(p => p.SignCondition);
        options.LoadWith<Sign>(p => p.SignDelineator);
        options.LoadWith<Sign>(p => p.SignFace);
        options.LoadWith<Sign>(p => p.SignIllumination);
        options.LoadWith<Sign>(p => p.SignToSignObstructions);
        options.LoadWith<Sign>(p => p.UniformTrafficControlCode);
        options.LoadWith<SignToSignObstruction>(p => p.SignObstruction);

我认为这样可以很好地解释我的对象图。我正在尝试查询符合特定搜索条件的支持对象(可能有人想要支持blah的帖子类型)。

如果我尝试撤回所有支持,我会获得大约2200个支持,并且需要17k个查询。

我尝试了另一个问题中提到的分组解决方案,但我想知道我做错了还是我的情况太复杂了。我删除了搜索条件,只是尝试返回所有支持。这导致大约21k查询并回退大约3000个支持。这是我的疑问:

                var group =
                from support in roadDataContext.Supports
                join sign in roadDataContext.Signs on support.SupportID equals sign.SupportID
                group sign by sign.Support
                into signGroup
                select signGroup;

我只是错过了一些简单的事情吗?感谢。

1 个答案:

答案 0 :(得分:2)

我们的L2S数据层犯了同样的错误。在某些情况下,我们的负载选项很荒谬。这是一个很难吸取的教训。

这称为SELECT N + 1问题。 1表示父实体,N表示正在加载的关联实体数。你可以期待L2S足够聪明并在一个巨大的查询中得到它,但遗憾的是并非如此。它将创建一个巨型查询,告诉它要加载的关联的ID,然后逐个检索这些关联。

也许最好的解决方法是使用投影,因此LINQ查询返回一个新对象,而不是一个实体。例如:

var fooDtos = from foo in db.Foo
              where foo.bar == "What a great example"
              select new fooDTO { FooName = foo.Name, FooBar = foo.Bar };

此查询返回IEnumerable&lt; FooDTO&gt;而不是IQueryable&lt; Foo&gt;。这有两个好处。首先,您要指示L2S具体检索哪些列,因此它不会执行SELECT *。此外,您不再需要DataLoadOptions,因为您可以在查询中查询所需的任何表,并从任何表中进行选择以生成DTO。