我一直在尝试编写一个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行长!
排名搜索中提琴!
答案 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。