将SQL转换为LINQ以进行相同的表查询

时间:2012-11-16 17:03:28

标签: sql linq linq-to-sql asp.net-mvc-4

我一直在尝试编写一个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: 这是我的数据库结构:

BookingID [PK] | TourID | RecordType | TourArea | TourGuideName | ALoadOfOtherFields

以下是一些示例数据:

1 | 1 | H |斗牛场|空

2 | 1 | T | null |牛头犬

3 | 2 | H |斗牛场|空

4 | 2 | T | null |牛头犬

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

只有一个H(头)记录,但可能有很多T(导游)记录。分组后,如果我在.Contains('bull')上用.Count()选择一个新的(像这个问题:How to use LINQ to SQL to create ranked search results?),那么我可以得到排名搜索(这是本练习的全部内容)

编辑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行长!

排名搜索中提琴!

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

为什么要转换呢?你可以打电话给你反对的SQl。