1

我一直在尝试编写一个 linq 查询,但 groupby 的性能非常慢,所以我用 SQL 编写了我的查询,它真的很快,但我无法让 linq pad 为我将它转换为 linq。任何人都可以帮我将此sql转换为Linq吗:

(SELECT mm.rcount, * FROM
(SELECT m.TourID AS myId, COUNT(m.RecordType) AS rcount FROM
(
((SELECT *
FROM Bookings h
WHERE h.RecordType = 'H' AND h.TourArea like '%bull%')
union
(SELECT *
FROM Bookings t
WHERE t.RecordType = 'T' and t.TourGuideName like '%bull%'))
) m
group by m.TourID) mm
INNER JOIN Bookings b ON mm.myId= b.TourID
WHERE b.RecordType = 'H');

这是我的 LINQ 工作,但迭代 200 多条记录需要 20 秒:

        var heads = from head in db.GetTable<BookingType>()
                    where head.RecordType == "H" &&
                    head.TourArea.Contains("bull")
                    select g;

        var tgs = from tourguides in db.GetTable<BookingType>()
                  where tourguides.RecordType == "T" &&
                  tourguides.TourGuideName.Contains("bull")
                  select tourguides;

        var all = heads.Union(tgs);
        var groupedshit = from r in all
                          group r by r.BookingID into g
                          select g;

        return heads;

编辑1: 这是我的数据库结构:

预订ID [PK] | 旅游ID | 记录类型 | 旅游区 | 导游姓名 | ALoadOfOtherFields

这是一些示例数据:

1 | 1 | H | 斗牛场 | 无效的

2 | 1 | T | 空 | 斗牛犬

3 | 2 | H | 斗牛场 | 无效的

4 | 2 | T | 空 | 斗牛犬

5 | 2 | T | 空 | 公牛邮票

只会有一个 H(头部)记录,但可能有许多 T(导游)记录。分组后,如果我在 .Contains('bull') 上使用 .Count() 选择一个新的(例如这个问题:如何使用 LINQ to SQL 创建排名搜索结果?),然后我可以获得排名搜索(即本练习的全部要点)。

编辑 2: 我在类本身中添加了搜索排名的属性,以避免将结果转换为键/值对的问题。我不知道这是否是最佳做法,但它有效。

    /// <summary>
    /// Search Ranking
    /// </summary>
    public int? SearchRank { get; set; }

然后我直接使用 linq-to-sql 执行 SQL 查询:

        IEnumerable<BookingType> results = db.ExecuteQuery<BookingType>
        ("(SELECT  mm.rcount AS SearchRank, b.* FROM (SELECT m.TourID AS myId, COUNT(m.RecordType) AS rcount FROM (((SELECT * FROM Bookings h WHERE h.RecordType = 'H' AND h.TourArea like '%{0}%') union (SELECT * FROM Bookings t WHERE t.RecordType = 'T' and t.TourGuideName like '%{0}%')) ) m group by m.TourID) mm INNER JOIN Bookings b ON mm.myId= b.TourID WHERE b.RecordType = 'H')", "bull");

我现在可以添加任意数量的“AND”和“OR”,而无需 Linq-to-sql(它生成的查询长达 200 行!

排名搜索中提琴!

4

2 回答 2

2

你根本不必使用union。你可以使用Where OR AND这样的东西应该工作:

 var result=    from b in DB.GetTable<Booking>()
                where (b.recordType =="H" || b.recordType=="T") 
                       &&b.TourArea.Contains("bull")
                group b by b.Booking_Id into g
                select g;
于 2012-11-16T17:14:23.100 回答
1

为什么要转换它?您可以只调用您已优化的 SQl。

于 2012-11-18T20:55:17.560 回答