[英]System.Linq.Expressions.Expression for .OrderBy function
I have a line section of my code that is repetitive. 我的代码的行部分是重复的。
You will see the lambda expression below repeat 4 times 您将看到下面的lambda表达式重复4次
x => x.GetValue<string>("City")).ThenByDescending(x => HelperFunctions.strToTZDateTime(x.GetValue<string>("EventStartStr"), x.GetValue<string[]>("EventTimeZone")[0].ToString())
The code example : 代码示例:
//SORT DATA
switch (SortDetails)
{
case ("Date"):
default:
if (SortOrder == "ASC")
{
_allEvents = _allEvents.OrderBy(x => HelperFunctions.strToTZDateTime(x.GetValue<string>("EventStartStr"), x.GetValue<string[]>("EventTimeZone")[0].ToString()));
}
else
{
_allEvents = _allEvents.OrderByDescending(x => HelperFunctions.strToTZDateTime(x.GetValue<string>("EventStartStr"), x.GetValue<string[]>("EventTimeZone")[0].ToString()));
}
break;
case ("Location"):
if (SortOrder == "ASC")
{
_allEvents = _allEvents.OrderBy(x => x.GetValue<string>("Country")).ThenBy(x => x.GetValue<string>("ProvinceState")).ThenBy(x => x.GetValue<string>("City")).ThenBy(x => HelperFunctions.strToTZDateTime(x.GetValue<string>("EventStartStr"), x.GetValue<string[]>("EventTimeZone")[0].ToString()));
}
else
{
_allEvents = _allEvents.OrderByDescending(x => x.GetValue<string>("Country")).ThenByDescending(x => x.GetValue<string>("ProvinceState")).ThenByDescending(x => x.GetValue<string>("City")).ThenByDescending(x => HelperFunctions.strToTZDateTime(x.GetValue<string>("EventStartStr"), x.GetValue<string[]>("EventTimeZone")[0].ToString()));
}
break;
}
I would like to take the first line and make it into something I can just plop into the OrderBy's. 我想采取第一行,并使其成为我可以进入OrderBy的东西。
Something like : 就像是 :
System.Linq.Expressions.Expression<Func<DynamicContent, DateTime>> sortLambda = x => HelperFunctions.strToTZDateTime(x.GetValue<string>("EventStartStr"), x.GetValue<string[]>("EventTimeZone")[0].ToString());
into : 进入:
allEvents = _allEvents.OrderBy(sortLambda);
Unfortunately that didn't seem to work well. 不幸的是,这似乎并没有奏效。
This console app should fix you up. 这个控制台应用程序应该修复你。 The sortLamda can be of any type, which hopefully answers your question about Dynamic Content.
sortLamda可以是任何类型,希望能回答有关动态内容的问题。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
internal class BoringEvent
{
public string EventStartStr { get; set; }
public string EventTimeZone { get; set; }
public string ProvinceState { get; set; }
public string City { get; set; }
public string Country { get; set; }
}
internal enum SortedBy
{
Ascending = 0,
Descending
}
class ExpressionsTest
{
internal static List<BoringEvent> _allEvents = new List<BoringEvent>();
internal static class HelperFunctions
{
public static DateTime strToTZDateTime(string startDate,
string timeZone)
{
//I'm too lazy to figure out dates by time zone.
//Your function already has the logic, so why bother.
//Let's assume the time zone is equal in this test case
return DateTime.Parse(startDate);
}
}
internal static void Main()
{
_allEvents.Add(new BoringEvent {
EventStartStr = "12/31/1999",
//let's party like it's 1999 - (yawn) I'm stuck at this event :<
EventTimeZone = "en-us",
City = "Philadelphia",
ProvinceState = "Pennsylvania",
Country = "United States of America"});
_allEvents.Add(new BoringEvent
{
EventStartStr = "01/01/1970",
EventTimeZone = "en-us",
City = "New York",
ProvinceState = "New York",
Country = "United States of America"
});
IEnumerable<BoringEvent> sortedEvents = null;
//sort by date
Console.WriteLine("Sorting Events by Ascending date...");
Expression<Func<BoringEvent, DateTime>> sortLamba = evt => HelperFunctions.strToTZDateTime(evt.EventStartStr, evt.EventTimeZone);
sortedEvents = _allEvents.SortEvents(SortedBy.Ascending, sortLamba);
Print(sortedEvents);
//sort by country, then state, then city, then date
Console.WriteLine("Sorting Events Desc by Country, then ProvinceState, then City, then Date");
Expression<Func<BoringEvent, object>>[] sortLamba2 = new Expression<Func<BoringEvent, object>>[]
{
evt => evt.Country,
evt => evt.ProvinceState,
evt => evt.City,
evt => HelperFunctions.strToTZDateTime(evt.EventStartStr, evt.EventTimeZone)
};
sortedEvents = _allEvents.SortEvents(SortedBy.Descending, sortLamba2);
Print(sortedEvents);
Console.Read();
}
private static void Print(IEnumerable<BoringEvent> events)
{
for(int i = 0; i < events.Count(); i++)
{
BoringEvent evt = events.ElementAt(i);
Console.WriteLine("Event: {0}", i.ToString());
Console.WriteLine("\tEventStartStr: {0}", evt.EventStartStr);
Console.WriteLine("\tEventTimeZone: {0}", evt.EventTimeZone);
Console.WriteLine("\tCity: {0}", evt.City);
Console.WriteLine("\tProvinceState: {0}", evt.ProvinceState);
Console.WriteLine("\tCountry: {0}", evt.Country);
}
}
}
internal static class EventExtensions
{
public static IEnumerable<TResult> SortEvents<TResult, T>(
this IEnumerable<TResult> events,
SortedBy sortByType,
params Expression<Func<TResult, T>>[] expressions)
{
IEnumerable<TResult> retVal = null;
switch(sortByType)
{
case SortedBy.Ascending:
retVal = EventExtensions.SortEventsAsc(events, expressions);
break;
case SortedBy.Descending:
retVal = EventExtensions.SortEventsDesc(events, expressions);
break;
default:
throw new InvalidOperationException(
string.Format("The SortedBy enumeration does not contain a case for the value of '{0}'.",
Enum.GetName(typeof(SortedBy), sortByType)));
}
return retVal;
}
public static IEnumerable<TResult> SortEventsAsc<TResult, T>(
this IEnumerable<TResult> events,
params Expression<Func<TResult, T>>[] expressions)
{
IOrderedEnumerable<TResult> sorted = null;
for(int i = 0; i < expressions.Count(); i++)
{
Expression<Func<TResult, T>> exp =
(Expression<Func<TResult, T>>)expressions[i];
Func<TResult, T> deleg = exp.Compile();
if(i == 0)
{
sorted = events.OrderBy(evt => deleg.Invoke(evt));
}
else
{
sorted = sorted.ThenBy(evt => deleg.Invoke(evt));
}
}
return sorted;
}
public static IEnumerable<TResult> SortEventsDesc<TResult, T>(
this IEnumerable<TResult> events,
params Expression<Func<TResult, T>>[] expressions)
{
IOrderedEnumerable<TResult> sorted = null;
for (int i = 0; i < expressions.Count(); i++)
{
Expression<Func<TResult, T>> exp =
(Expression<Func<TResult, T>>)expressions[i];
Func<TResult, T> deleg = exp.Compile();
if (i == 0)
{
sorted = events.OrderByDescending(evt => deleg.Invoke(evt));
}
else
{
sorted = sorted.ThenByDescending(evt => deleg.Invoke(evt));
}
}
return sorted;
}
}
I believe that the OrderBy
method takes a Func<T1,T2>
parameter, so you could possibly do this... 我相信
OrderBy
方法采用Func<T1,T2>
参数,所以你可能会这样做......
var func = x => HelperFunctions.strToTZDateTime(x.GetValue<string>("EventStartStr"), x.GetValue<string[]>("EventTimeZone")[0].ToString());
then pass func
into _allEvents = _allEvents.OrderBy(func);
然后将
func
传递给_allEvents = _allEvents.OrderBy(func);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.