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