开发者

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

301

the 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;

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜