我的代码的行部分是重复的。
您将看到下面的lambda表达式重复4次
x => x.GetValue<string>("City")).ThenByDescending(x => HelperFunctions.strToTZDateTime(x.GetValue<string>("EventStartStr"), x.GetValue<string[]>("EventTimeZone")[0].ToString())
代码示例:
//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;
}
我想采取第一行,并把它变成我可以进入OrderBy的东西。
类似的东西:
System.Linq.Expressions.Expression<Func<DynamicContent, DateTime>> sortLambda = x => HelperFunctions.strToTZDateTime(x.GetValue<string>("EventStartStr"), x.GetValue<string[]>("EventTimeZone")[0].ToString());
进入:
allEvents = _allEvents.OrderBy(sortLambda);
不幸的是,这似乎并没有奏效。
答案 0 :(得分:1)
此控制台应用应该可以解决您的问题。 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;
}
}
答案 1 :(得分:0)
我相信OrderBy
方法需要Func<T1,T2>
参数,所以你可能会这样做......
var func = x => HelperFunctions.strToTZDateTime(x.GetValue<string>("EventStartStr"), x.GetValue<string[]>("EventTimeZone")[0].ToString());
然后将func
传递给_allEvents = _allEvents.OrderBy(func);