我有一个课程表,我想对其中的几个字段执行文本搜索。但是,应该订购搜索:例如,课程有Description
字段和Keywords
字段。搜索应优先于ToPagedList()
找到的值。一切都应该按日期排序,但只有在考虑优先级之后。
我也在plot
的最后使用Skip()
(我认为它只使用Top()
和string[] word = /*Search words*/
var data = db.LessonsLearneds.Where(dbRecord => words.Any(word =>
dbRecord.SearchKeywords.StartsWith(word + ",") ||
dbRecord.SearchKeywords.Contains("," + word + ",") ||
dbRecord.SearchKeywords.EndsWith("," + word)))
.Select(x => new { Record = x, Order = 1 });
data = data.Union(
db.LessonsLearneds
.Where(dbRecord => words.Any(word => dbRecord.Title.Contains(word)))
.Select(x => new { Record = x, Order = 2 }));
data = data.Union(
db.LessonsLearneds
.Where(dbRecord => words.Any(word => dbRecord.Description.Contains(word)))
.Select(x => new { Record = x, Order = 3}));
data = data.Union(
db.LessonsLearneds
.Where(dbRecord => words.Any(word => dbRecord.Lesson.Contains(word)))
.Select(x => new { Record = x, Order = 4 }));
return data
.Distinct()
.OrderBy(x => x.Order)
.ThenByDescending(x => x.Record.Date)
.Select(x => x.Record)
.ToPagedList(pageNumber, pageSize);
来管理网页)
这是我到目前为止所做的:
Distinct()
总的来说,除了Distinct()
之外,这段代码几乎可以实现我想要的功能。这里的每个联合都可以检索相同的记录,因此我可能会多次收到它,而Order
不会因虚拟Distinct
字段而强制唯一性。我无法将Select(x => x.Record)
放在ToPagedList(..)
之后因为The method 'Skip' is only supported for sorted input in LINQ to Entities.
需要对该集进行排序(导致:Order
异常)
有什么想法吗?
到目前为止我有一个:在Distinct
之后添加{{1}}字段,但这意味着我必须编写两次包含检查,我认为这是非常难看的解决方案。
答案 0 :(得分:1)
您可以将Distinct
替换为GroupBy
和Select
,如下所示:
return data
.GroupBy(x => x.Record)
.Select(g => g.OrderBy(x => x.Order).ThenByDescending(x => x.Record.Date).First())
.OrderBy(x => x.Order)
.ThenByDescending(x => x.Record.Date)
.Select(x => x.Record)
.ToPagedList(pageNumber, pageSize);
这种方法的不幸副作用是你需要在第一个OrderBy
内重复Select
,但它应该产生你正在寻找的结果。
答案 1 :(得分:1)
首先,由于由于Order
值不同而要投射唯一记录,因此将Union
运算符替换为Concat
(这是SQL UNION ALL
的LINQ等价物)。
string[] word = /*Search words*/
var data = db.LessonsLearneds.Where(dbRecord => words.Any(word =>
dbRecord.SearchKeywords.StartsWith(word + ",") ||
dbRecord.SearchKeywords.Contains("," + word + ",") ||
dbRecord.SearchKeywords.EndsWith("," + word)))
.Select(x => new { Record = x, Order = 1 });
data = data.Concat(
db.LessonsLearneds
.Where(dbRecord => words.Any(word => dbRecord.Title.Contains(word)))
.Select(x => new { Record = x, Order = 2 }));
data = data.Concat(
db.LessonsLearneds
.Where(dbRecord => words.Any(word => dbRecord.Description.Contains(word)))
.Select(x => new { Record = x, Order = 3}));
data = data.Concat(
db.LessonsLearneds
.Where(dbRecord => words.Any(word => dbRecord.Lesson.Contains(word)))
.Select(x => new { Record = x, Order = 4 }));
然后将Distinct
替换为GroupBy
,使用x.Record
作为密钥,并为每个分组取{min} Order
,其余部分与当前查询一样:
return data
.GroupBy(x => x.Record)
.Select(g => new { Record = g.Key, Order = g.Min(x => x.Order) })
.OrderBy(x => x.Order)
.ThenByDescending(x => x.Record.Date)
.Select(x => x.Record)
.ToPagedList(pageNumber, pageSize);