我正在使用Lucene.net构建一个MyListOfIds As List(Of Integer)
,然后我将其传递给我的Linq服务。然后我按如下方式搜索数据库
Return _EventRepository.Read().Where(Function(e) MyListOfIds.Contains(e.ID)).ToList
现在我知道Lucene已根据每个学期的重量排序MyListOfIds
。令人痛苦的是Linq在SQL搜索中失去了这个顺序。
我的问题:如何在构建Lambda表达式时保留该排序顺序?
我尝试使用LINQPad来查看查询是如何构建的,但是因为我必须声明变量LINQPad并没有向我显示结果SQL: - (
这是我在LINQPad
中尝试过的内容Dim i As New List(Of Integer)
i.Add(1)
i.Add(100)
i.Add(15)
i.Add(3)
i.Add(123)
Dim r = (From e In Events
Where i.Contains(e.ID)
Select e)
注意:我的示例是在VB.NET中,但我不介意回复是否在C#
答案 0 :(得分:2)
我会说LINQ to SQL查询会以数据库的自然顺序(可能是主键?)返回数据,因为SQL中的IN
条件(.Contains
应该是ORDER
翻译为)没有指定任何IComparer<T>
,你的LINQ表达也没有。如果您将其视为普通的SQL语句,很明显您无法轻松地以这种方式指定顺序。
为了对加载的数据进行排序,您可以将其取消排序,然后按照Lucene的已知顺序对枚举进行排序。您可能必须自己编写(即客户{{1}})。
答案 1 :(得分:2)
从L2S查询中获取无序结果,然后使用the .Select overload that gives ordinal position以与L2O(linq-to-objects)查询中的List相同的顺序重新排序。 E.g:
var someResult = _EventRepository.Read().Where(e => MyListOfIds.Contains(e.ID)).ToList();
var someResultOrdered =
from sr in someResult
join lid in MyListOfIds.Select((v, i) => new { v, i }) on sr.ID equals lid.v
orderby lid.i
select sr;
答案 2 :(得分:2)
正如我提到的那样,我认为Dictionary方法是可行的方法。我会这样做:
Public Function GetLuceneSearchResults(ByVal ids As List(Of Integer)) As List(Of Domain.Event) Implements IEventService.GetLuceneSearchResults
Dim Results = (From e In _EventRepository.Read()
Where ids.Contains(e.ID)
Select e).ToDictionary(Function(e) e.ID, Function(e) e)
Return (From i In ids
Where Results.ContainsKey(i)
Select Results(i)).ToList()
End Function
第一个查询返回一个以事件id为键的Dictionary,并将事件本身作为值。您可以通过这种方式获得哈希查找的性能优势。
答案 3 :(得分:1)
你可能需要一个IDictionary,你的密钥只是一个增量(如一个标识列)和你Lucene实际id的值。
然后,在您的LINQ2SQL语句中,而不是执行此“where”子句,您可以使用数据库中的列在“字典值”中执行“连接”。在LINQ中,按字典键排序。
编辑:添加示例
以下是一个例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
var ids = new Dictionary<int, int>();
//key is just a sort sequence, value is the ID from Lucene
ids.Add(1, 27);
ids.Add(2, 25);
ids.Add(3, 29);
var ctx = new DataClasses1DataContext();
var tabs = (from t in ctx.Tabs
where ids.Values.Contains(t.TabID)
select t).ToList();
var sorted = from t in tabs
join id in ids on t.TabID equals id.Value
orderby id.Key
select t;
foreach (var sortedItem in sorted) {
Console.WriteLine(sortedItem.TabID);
}
Console.ReadLine();
}
}
}
答案 4 :(得分:1)
愿意接受建议!
Public Function GetLuceneSearchResults(ByVal ids As List(Of Integer)) As List(Of Domain.Event) Implements IEventService.GetLuceneSearchResults
Dim Results = _EventRepository.Read().Where(Function(e) ids.Contains(e.ID)).AsQueryable
Dim Output As New List(Of Domain.Event)
For Each i In ids
Output.Add(Results.Where(Function(e) e.ID = i).SingleOrDefault)
Next
Return Output
End Function
现在抛开性能推测,这肯定与预期完全一致。我很想听听你对性能提升的看法,或者这只是出去吃午饭的方式。感谢。