为什么我的linq订购不起作用

时间:2011-09-23 05:32:07

标签: c# linq linq-to-objects

尝试按logtype或logType然后按Date Date订购日志但不起作用。我错过了什么?

      public enum LogType
    {
        Fatal,
        Error,
        Warn,
        Info,
        Debug,
        None,
    }
    public class Log
    {
        public DateTime LoggedDateTime { get; set; }
        public string Message { get; set; }
        public LogType LoggedType { get; set; }
        public override string ToString()
        {
            return string.Format("LogType: {0} Datetime: {1} Message: {2}", LoggedType, LoggedDateTime, Message);
        }
    }
    class Program
    {
        static void Main()
        {
            var logFatal = new Log
                               {
                                   LoggedDateTime = new DateTime(2011, 2, 22),
                                   Message = "Hi am a Fatal message",
                                   LoggedType = LogType.Fatal
                               };

            var logInfo = new Log
            {
                LoggedDateTime = new DateTime(2013, 2, 22),
                Message = "Hi I am a Info message",
                LoggedType = LogType.Info
            };

            var logError = new Log
            {
                LoggedDateTime = new DateTime(2010, 2, 22),
                Message = "Hi I am a Error message",
                LoggedType = LogType.Error
            };

            var logWarning = new Log
            {
                LoggedDateTime = new DateTime(2014, 2, 22),
                Message = "Hi I am a Warning message",
                LoggedType = LogType.Warn
            };
            List<Log> logs = new List<Log> { logWarning, logError, logInfo, logFatal };

            Console.WriteLine("Not Ordered");
            Console.WriteLine("");
            logs.ForEach(x=>Console.WriteLine(x.LoggedType));



            var orderedLogs = logs.OrderBy(x => x.LoggedType == LogType.Fatal)
                .ThenBy(x => x.LoggedType == LogType.Error)
                .ThenBy(x => x.LoggedType == LogType.Warn)
                .ThenBy(x => x.LoggedDateTime).ToList();

            Console.WriteLine("Ordered by logType fatal first and NOT WORKING");
            Console.WriteLine("");

            orderedLogs.ForEach(x=>Console.WriteLine(x.LoggedType));

            Console.WriteLine("");
            Console.WriteLine("Ordered by logType fatal first and NOT WORKING");//NOT WORKING
            List<Log> orderedFatal = logs.OrderBy(x => x.LoggedType == LogType.Fatal).ToList();
            orderedFatal.ForEach(x => Console.WriteLine(x.LoggedType));

            Console.WriteLine("");
            Console.WriteLine("Sorted by datetime AND WORKS"); //THIS IS THE ONLY ONE THAT WORKS
            logs.Sort((x,y)=>x.LoggedDateTime.CompareTo(y.LoggedDateTime));
            logs.ForEach(x => Console.WriteLine(x.LoggedDateTime));


            Console.Read();
        }
    }

感谢您的任何建议

4 个答案:

答案 0 :(得分:4)

问题是在false之前订购了true。 因此,首先在你的订单中来到那些不是致命的。那些先来的不是错误等。

您可以使用不等式来使其有效:

x => x.LoggedType != LogType.Fatal

或使用OrderByDescendingThenByDescending

但我更愿意给出枚举的命令:

public enum LogType : int
    {
        Fatal = 5,
        Error = 4,
        Warn = 3,
        Info = 2,
        Debug = 1,
        None = 0,
}

然后只使用此值:

var orderedLogs = logs.OrderByDescending(x => x.LoggedType);

答案 1 :(得分:0)

logWarninglogError都有LoggedType = LogType.Error

另一点:您应该为LogType实施/使用IComparer ...请参阅http://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx上的MSDN

基本上是这样的:

public class LogComparer : IComparer<Log>
{
    public int Compare(Log x, Log y)
    {
        if ( x == y ) return 0;
        if ( x.LoggedType == y.LoggedType ) return 0;
        if ( x.LoggedType == LogType.Fatal ) return 1;
        if ( y.LoggedType == LogType.Fatal ) return -1;
        // etc.
    }
}

// Usage similar to this
logs.OrderBy(x => x, new LogComparer());

答案 2 :(得分:0)

您需要执行以下操作:

var orderedLogs = logs.GroupBy(l => l.LoggedType)
                    .OrderBy(g => g.Key)
                    .SelectMany(g => g.OrderByDescending(l => l.LoggedDateTime)).ToList();

答案 3 :(得分:0)

您可以按LoggedType字段对集合进行排序,然后使用以下代码中的LoggedDateTime字段对集合进行排序:

var orderedLogs = logs.OrderBy(x => x.LoggedType) // not x => x.LoggedType == LogType.Fatal
    .ThenBy(x => x.LoggedDateTime).ToList();

我认为将通过枚举的整数表示进行排序。所以你的枚举会有致命,错误,警告等。或者你可以使用IComparer(来自Yahia的答案)来制定你自己的比较规则。