我在下面的变量中有一些Ids
存储:
List<int> Ids;
现在我想根据上面的ID获取记录,但是上面的顺序与Ids.
例如:记录在数据库中是这样的:
员工:
Id
1
2
3
4
5
现在,如果Ids数组保存这样的ID: 4,2,5,3,1 ,那么我只是按此顺序获取记录:
查询:
var data = context.Employee.Where(t => Ids.Contains(t.Id)).ToList();
但是上面的查询给出的输出就像它在表格中一样:
Id
1
2
3
4
5
预期输出:
Id
4
2
5
3
1
更新:我已经尝试过以下解决方案,但由于这是实体框架,因此无法解决问题:
var data = context.Employee.Where(t => Ids.Contains(t.Id))
.OrderBy(d => Ids.IndexOf(d.Id)).ToList();
要使上述解决方案正常工作,我必须添加到列表中:
var data = context.Employee.Where(t => Ids.Contains(t.Id)).ToList()
.OrderBy(d => Ids.IndexOf(d.Id)).ToList();
但我不想在内存中加载数据,然后过滤掉我的记录。
答案 0 :(得分:1)
如果没有存储过程,您可以使用属于规范函数的Union
和?:
我无法想象其他方式。
<强>:吗
您可以使用它为每个id值分配一个weigth,然后按weigth排序。此外,您必须生成?:using dynamic linq。
What is the equivalent of "CASE WHEN THEN" (T-SQL) with Entity Framework?
Dynamically generate LINQ queries
<强>联盟强>
我认为这是获得它的更简单的方法。在这种情况下,您可以为每个Id添加Where / Union。
编辑1
关于使用Union,您可以使用与此类似的代码
IQueryable<Foo> query = context.Foos.AsQueryable();
List<int> Ids = new List<int>();
Ids.AddRange(new[] {3,2,1});
bool first = true;
foreach (int id in Ids)
{
if (first)
{
query = query.Where(_ => _.FooId == id);
first = false;
}
else
{
query = query.Union(context.Foos.Where(_ => _.FooId == id));
}
}
var results = query.ToList();
这会生成跟随查询
SELECT
[Distinct2].[C1] AS [C1]
FROM ( SELECT DISTINCT
[UnionAll2].[C1] AS [C1]
FROM (SELECT
[Distinct1].[C1] AS [C1]
FROM ( SELECT DISTINCT
[UnionAll1].[FooId] AS [C1]
FROM (SELECT
[Extent1].[FooId] AS [FooId]
FROM [Foos] AS [Extent1]
WHERE [Extent1].[FooId] = @p__linq__0
UNION ALL
SELECT
[Extent2].[FooId] AS [FooId]
FROM [Foos] AS [Extent2]
WHERE [Extent2].[FooId] = @p__linq__1) AS [UnionAll1]
) AS [Distinct1]
UNION ALL
SELECT
[Extent3].[FooId] AS [FooId]
FROM [Foos] AS [Extent3]
WHERE [Extent3].[FooId] = @p__linq__2) AS [UnionAll2]
) AS [Distinct2]
p__linq__0 = 3
p__linq__1 = 2
p__linq__2 = 1
编辑2
我认为最好的方法是在内存方法中,因为它具有相同的网络负载,EF不会生成丑陋的查询,这些查询无法在与SQL Server不同的数据库上运行,代码更具可读性。在您的特定应用程序中可能是union /哪里更好。所以,通常我会建议你尝试一下内存方法,如果你有[性能]问题,你可以检查一下是否更好。
答案 1 :(得分:1)
由于当您未指定ORDER BY
plot command时返回数据的顺序,您必须添加ORDER BY
以指示您希望如何排序。不幸的是,您必须根据内存中的对象/值进行排序,并且不能在SQL查询中使用它进行排序。
因此,您可以做的最好的事情是在从数据库中检索数据后订购内存。
var data = context.Employee
// Add a criteria that we only want the known ids
.Where(t => Ids.Contains(t.Id))
// Anything after this is done in-memory instead of by the database
.AsEnumerable()
// Sort the results, in-memory
.OrderBy(d => Ids.IndexOf(d.Id))
// Materialize into a list
.ToList();