I use EF Core and I want to select only the IDs I need, as I would do it, I use an In SQL expression. How can I get the result in the same order as the Ids in the array? And fill OrderNum value in result Dto?
public IEnumerable<ResultDto> Foo()
{
int[] validIds = { 100, 2, 3, 4, 5, 6, 8, 13, 14, 16, 22 };
// Without the required sorting
var query = dc.LeaveRequests.Where(x => validIds.Contains(x.Id));
...
}
class Model
{
public int Id { get; set; }
public string Name { get; set; }
}
class ResultDto
{
public int Id { get; set; }
public string Name { get; set; }
public int OrderNum { get; set; }
}
I would create an index lookup dictionary with the ID as the key and the index as the value. You can then order the result by looking up the index in the dictionary in O(1) time. (using .IndexOf
on the array would be an O(n) operation)
int[] validIds = { 100, 2, 3, 4, 5, 6, 8, 13, 14, 16, 22 };
var result = dc.LeaveRequests.Where(x => validIds.Contains(x.Id)).AsEnumerable();
var indexLookup = validIds.Select((v,i) => (v,i)).ToDictionary(x => x.v, x => x.i);
var sortedResult = result.OrderBy(x => indexLookup[x.Id]);
Perhaps an even more simple solution would be to join
the validIds with the result of the query. The order from the first collection is preserved and the join will use a HashSet internally for the lookup. It would also perform better since ordering the result using OrderBy
can be avoided.
int[] validIds = { 100, 2, 3, 4, 5, 6, 8, 13, 14, 16, 22 };
var result = dc.LeaveRequests.Where(x => validIds.Contains(x.Id)).AsEnumerable();
var sortedResult = validIds.Join(result, x => x, x => x.Id, (x, y) => y);
Try OrderBy
if you don't have more requirements.
var query = dc.LeaveRequests
.Where(x => validIds.Contains(x.Id))
.OrderBy(x => validIds.IndexOf(x.Id))
.Select(x => new OrderNum {
Id = x.Id,
Name = x.Name,
OrderNum = //fill OrderNum here,
})
.AsEnumerable();
Assuming that the valid ids may be provided in another order, you could order by the index position of the id in the validIds
(using a list instead of an array) and map the index position of the result to the OrderNum
property:
var query = dc.LeaveRequests
.Where(x => validIds.Contains(x.Id))
.OrderBy(x => validIds.IndexOf(x.Id))
.Select((x, i) => new ResultDto
{
Id = x.Id,
Name = x.Name,
OrderNum = i
});
var results = dc.LeaveRequests
.Where(x => validIds.Contains(x.Id))
.Select(x => new ResultDto
{
Id = x.Id,
Name = x.FechaCreacion,
})
.AsEnumerable()
.OrderBy(x => validIds.IndexOf(x.Id))
.ToList();
for (int i = 0; i < results.Count; i++)
{
results[i].OrderNum = i;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.