1

我使用 BLToolKit 作为 ORM 映射器。

我的问题是,它生成了错误的 SQL。

我有这个查询:

var qry = from i in s.Query<ChannelDTO>() 
            join o in s.Query<StorageShelfDTO>() on i.Id equals o.ChannelID into p1
            select new {i.Id, n = p1.Count()};

        var qry2 = qry;
        qry2 = qry2.Where(x => x.n == 0);
        Debug.Print("Entrys: " + qry2.ToList().ToString());

生成此 SQL:

SELECT
[x].[Id] as [Id1]  
FROM
(
SELECT
    (
        SELECT
            Count(*)
        FROM
            [WMS_StorageShelf] [t1]
        WHERE
            [i].[ID] = [t1].[ChannelID]
    ) as [c1],
    [i].[ID] as [Id]
FROM
    [WMS_Channel] [i]
) [x]
WHERE
[x].[c1] = 0

缺少外部选择中的计数字段!

但是当我删除条件时:

 qry2 = qry2.Where(x => x.n == 0);

然后生成正确的 SQL。

4

1 回答 1

0

生成的查询是正确的。

你有你的初始 linq 语句:

var qry = from i in s.Query<ChannelDTO>() 
            join o in s.Query<StorageShelfDTO>() on i.Id equals o.ChannelID into p1
            select new {i.Id, n = p1.Count()};

这将生成类似于以下内容的 SQL:

SELECT
    (
        SELECT
            Count(*)
        FROM
            [WMS_StorageShelf] [t1]
        WHERE
            [i].[ID] = [t1].[ChannelID]
    ) as [c1],
    [i].[ID] as [Id]
FROM
    [WMS_Channel] [i]

现在,当您将第二部分添加到查询 (qry2) 中时,它将被添加到您的原始查询中,因为它使用的是延迟执行。因此,在执行时,组成的最终查询如下所示:

var finalQuery = (from i in s.Query<ChannelDTO>() 
                 join o in s.Query<StorageShelfDTO>() on i.Id equals o.ChannelID into p1
                 select new {i.Id, n = p1.Count()}).Where(x => x.n == 0)

这就是为什么您按原样生成 SQL 的原因。

如果您不想要延迟执行并且实际上想要两个不同的查询,那么调用.ToList()您的第一个查询以强制立即执行,您将看到您期望的查询。

像这样:

var qry = (from i in s.Query<ChannelDTO>() 
            join o in s.Query<StorageShelfDTO>() on i.Id equals o.ChannelID into p1
            select new {i.Id, n = p1.Count()}).ToList();
于 2014-03-13T00:14:32.210 回答