开发者

LINQ query needs either ascending or descending in the same query

Is there anyway this code can be refactored? The only difference is the order by part.

Idealy I'd like to use a delegate/lambda expression so the code is reusable but I don't know how to conditionally add and remove the query operators OrderBy and OrderByDescending

var linq = new NorthwindDataContext();

        var query1 = linq.Customers
            .Where(c => c.ContactName.StartsWith("a"))
            .SelectMany(cus=>cus.Orders)
            .OrderBy(ord => ord.OrderDate)
            .Select(ord => ord.CustomerID);

        var query2 = linq.Customers
            .Where(c => c.ContactName.StartsWith("a"))
            .SelectMany(cus => cus.Orders)
            .OrderByDescending(ord => ord.Order开发者_运维技巧Date)
            .Select(ord => ord.CustomerID);


You can create your own reusable extension method which will do this:

public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>
    (this IQueryable<TSource> source,
     Expression<Func<TSource, TKey>> keySelector,
     bool ascending)
{
     return ascending ? source.OrderBy(keySelector)
          : source.OrderByDescending(keySelector);
}

and similarly for ThenBy:

public static IOrderedQueryable<TSource> ThenBy<TSource, TKey>
    (this IOrderedQueryable<TSource> source,
     Expression<Func<TSource, TKey>> keySelector,
     bool ascending)
{
     return ascending ? source.ThenBy(keySelector)
          : source.ThenByDescending(keySelector);
}


You can split your query up into bits, and use control flow logic. LINQ to SQL will magically construct the correct query as if you had typed it all one line! The reason this works is that the query is not sent to the database until you request the data, but instead is stored as an expression.

var linq = new NorthwindDataContext();
var query = linq.Customers
    .Where(c => c.ContactName.StartsWith("a"))
    .SelectMany(cus=>cus.Orders);

IOrderedQueryable<Order> query2;
if (useAscending) {
    query2 = query.OrderBy(ord => ord.OrderDate);
} else {
    query2 = query.OrderByDescending(ord => ord.OrderDate);
}

var query3 = query2.Select(ord => ord.CustomerID);


return from T in bk.anbarsabts
       where T.kalaname == str
       orderby T.date descending
       select new { T.date, T.kalaname, T.model, T.tedad };


With numbers, etc you can normally just negate the 'ordering variable'.

With DateTime, I am not so sure. You could try using a Timespan.


Well, If you have a condition where you decide if the order by is ascending or descending you can use this

var query1 = linq.Customers
.Where(c => c.ContactName.StartsWith("a"))
.SelectMany(cus=>cus.Orders)

if(SortAscending)
   query1 = query1.OrderBy(ord => ord.OrderDate);
else
   query1 = query1.OrderByDescending(ord => ord.OrderDate);

var query2 = query1.Select(ord => ord.CustomerID);
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜