How to order a List by the order of another List?
I have a method as follows. It returns a list of MyTypes
which appear to be ordered 开发者_如何转开发by myType.Id
ascending by default. I'd like this list to be ordered by the ids
parameter I pass into the method.
public List<MyType> GetMyTypes(List<int> ids)
{
return (from myType in db.MyTypes
where ids.Contains(myType.Id)
select new MyType
{
MyValue = myType.MyValue
}).ToList();
}
So if ids
contains
302
300 301the List returned contains items in ascending order.
What do I need to do to return List<MyType>
in the order of ids
?
Thanks
edit: I've tried orderby ids.IndexOf(myType.Id)
but it throws the exception Method 'Int32 IndexOf(Int32)' has no supported translation to SQL.
EDIT: now that the mistake I made in understanding the requirement has been pointed out, I suggest this as a more performant method of achieving the desired result:
public static List<MyType> GetMyTypes(List<int> ids)
{
int index = 0;
Dictionary<int, int> positions = ids.ToDictionary(c => c, c => index++);
MyType[] results = new MyType[ids.Count];
foreach (MyType aType in (from myType in db.MyTypes
where ids.Contains(myType.Id)
orderby myType.Id
select myType))
{
results[positions[aType.Id]] = aType;
}
return results.ToList();
}
This won't do a search through the ids list for every element in db.MyTypes (which is a good thing: it'll be fast!).
My original (incorrect) answer:
Use an orderby clause.
public List<MyType> GetMyTypes(List<int> ids)
{
return (from myType in db.MyTypes
where ids.Contains(myType.Id)
orderby myType.Id
select new MyType
{
MyValue = myType.MyValue
}).ToList();
}
It's not clear what type of object db.MyTypes returns but, at a guess, the code could be simplified a little by avoiding the newing up of more MyType objects.
public List<MyType> GetMyTypes(List<int> ids)
{
return (from myType in db.MyTypes
where ids.Contains(myType.Id)
orderby myType.Id
select myType).ToList();
}
Daniel is nearly right, but an easy way to use the order of the incoming list is to order by the index of the ID in that list:
public List<MyType> GetMyTypes(List<int> ids)
{
return (from myType in db.MyTypes
where ids.Contains(myType.Id)
orderby ids.IndexOf(myType.Id)
select myType).ToList();
}
Note I don't know if that will work with a SQL query, so this may be Linq-to-objects only. It could also be very inefficient with large lists of ids.
The following worked:
public List<MyType> GetMyTypes(List<int> ids)
{
var unordered = (from myType in db.MyTypes
where ids.Contains(myType.Id)
select new MyType
{
MyValue = myType.MyValue
}).ToList();
var ordered = (from uo in unordered
orderby ids.IndexOf(uo.Id)
select uo).ToList();
return ordered;
}
精彩评论