开发者

Can LINQ order by a column index? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers. 开发者_如何转开发

We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.

Closed last month.

Improve this question

I'm struggling to find LINQ orderby examples, where data is ordered by a column index. Is this possible to do?

Thank you


There's no such concept as a column in LINQ, only fields and properties. What you mean is probably to specify the index of a property in an anonymous type you create:

from p in persons
orderby 1
select new { p.FirstNam, p.LastName }

That's not possible, because a) you can't order by a projection property (output value in the anonymous type), and b) you can't order by index. To work around a), you can use the "into" keyword:

from p in persons
orderby p.FirstName
select new { First = p.FirstName, Last = p.LastName }
into tmp
   orderby tmp.First
   select tmp;

If you use a LINQ provider based on IQueryable (like LINQ to SQL, as opposed to LINQ to objects which is based on IEnumerable), you could parse the expression tree, find the expression based on some index, and add the corresponding OrderBy method call.

var query = from p in persons 
            select new { Name = p.FirstName + " " + p.LastName, ...}
query = AddOrderByPosition (query, 1);
foreach (var p in query) {...}

AddOrderByPosition would have to create a new expression tree that uses the original query expression as a source (a sub query, which is essentially what "into" creates too) and add a call to OrderBy at the end (no need for Select). You want to read the C# specs' chapter about transformation of query expressions first, and you should have some experience with reflection and expressions if you want to get this done in a sensible amount of time.

If you want that, I have some sample code I can provide.


I know that it is not possible to change index.


I think you might mean Select with an Indexer? If so, the following is an example from one of my Linq queries:

var tmp = 
    from container in Container
    where container.ContainerTypeID == 2
    select new { ContainerID = container.ContainerID, TypeID = container.ContainerTypeID};

// The indexer cannot be used with the query expression format, so we need to convert to dot notation.
// We also need to convert tmp to an Enumerable so that .NET performs the query instead of SQL.
var results = tmp.AsEnumerable().Select((row, index) => new { row.ContainerID, row.TypeID, ContainerIndex = index });


In LinqToSql, you have a class mapped to the database, with property names that do not change. These properties are mapped to the database using attributes. The database column name is in the attribute.

If you want to change the column name at design time, you can use the designer (if the class is autogenerated) or alter the attribute yourself.

If you want to change the column name at run time, you should provide an XmlMappingSource. This will override the mapping from the attributes.


I had to do this earlier today (but using multiple columns - even harder). LINQ was definitely not working for me, especially with a dynamic number of indexes being passed in.

You may have better luck pulling your objects into a List<T> and then using the .Sort method on them. Here's a dirty example that may guide you.

var query = db.MyTable.Where(x => something);
var list = query.ToList();
list.Sort((x, y) => {
    // decide how you want to compare
    // use string.compare or another method
    // return -1, 0, 1 as is normal for sorting

    return 0; //Replace this
});


Let's say you have an array of strings, and each string contains structured text with a fixed number of columns (fields) of data. (Like the kind of data where if it was in a text file you might use a command line tools like 'awk'.) Then the following C# code demonstrates how you could sort by a specific column using LINQ:

String[] sData = 
{
  "1  BMW     Germany  40000",
  "2  Volvo   Sweden   35000",
  "3  Ferrari Italy   200000",
  "4  Subaru  Japan    30000"
};
int sortCol = 3;
foreach (string sOut in sData.OrderBy(x => Convert.ToInt32(Regex.Split(x, @"\s+")[sortCol])))
{
  Console.WriteLine(sOut);
}

In the above, we are sorting by the 4th column, which is numeric.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜