【问题标题】:c# linq order by null lastc# linq order by null last
【发布时间】:2019-01-03 14:06:05
【问题描述】:

我有一个日志列表作为字符串。它像这样输出给我:

"2018.07.26 10:35:06:7889: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:06:7959: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Requested (SOCS)... Success",
"2018.07.26 10:35:06:9019: DAIW - New Session Requested... Success (Start Session Thread Started)",
"2018.07.26 10:35:06:9169: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Thread (SOCS)... Success",
"2018.07.26 10:35:06:9229: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:07:1219: DAIW - Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)",
"2018.07.26 10:35:07:1229: c0c2311a-b509-4e6e-a236-80e2d86f2647 - Client Successfully Retrieved Session",
"2018.07.26 10:35:07:1429: 4d50b064-d269-4256-a187-82a3f9402735 - End Session Requested - Thread started"

这是错误的顺序。 应该是这个顺序:

"2018.07.26 10:35:06:7889: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:06:7959: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Requested (SOCS)... Success",
"2018.07.26 10:35:06:9169: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Thread (SOCS)... Success",
"2018.07.26 10:35:06:9229: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",,
"2018.07.26 10:35:07:1429: 4d50b064-d269-4256-a187-82a3f9402735 - End Session Requested - Thread started"
"2018.07.26 10:35:06:9019: DAIW - New Session Requested... Success (Start Session Thread Started)",
"2018.07.26 10:35:07:1219: DAIW - Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)",
"2018.07.26 10:35:07:1229: c0c2311a-b509-4e6e-a236-80e2d86f2647 - Client Successfully Retrieved Session"

看来旧系统只是按日期排序。 我创建了一个模型并提取了我需要的部分。 模型如下所示:

public class TroposLog
{
    public DateTime Created { get; set; }
    public string UserName { get; set; }
    public string SessionId { get; set; }
    public string ActionName { get; set; }
    public string Message { get; set; }
}

现在这给了我一些工作。 但我无法按照我想要的方式订购它。 如果我这样做:

return troposLogs
           .OrderBy(m => m.UserName)
           .ThenBy(m => m.SessionId)
           .ThenBy(m => m.Created);

它返回这个命令:

"2018.07.26 10:35:06:7889: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:06:7959: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Requested (SOCS)... Success",
"2018.07.26 10:35:06:9169: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Thread (SOCS)... Success",
"2018.07.26 10:35:06:9229: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:07:1429: 4d50b064-d269-4256-a187-82a3f9402735 - End Session Requested - Thread started",
"2018.07.26 10:35:07:1229: c0c2311a-b509-4e6e-a236-80e2d86f2647 - Client Successfully Retrieved Session",
"2018.07.26 10:35:06:9019: DAIW - New Session Requested... Success (Start Session Thread Started)",
"2018.07.26 10:35:07:1219: DAIW - Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)"

我也试过了:

return troposLogs.OrderBy(m => m.UserName != null).ThenBy(m => m.UserName);

返回此订单:

"2018.07.26 10:35:06:7889: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:06:7959: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Requested (SOCS)... Success",
"2018.07.26 10:35:06:9169: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Thread (SOCS)... Success",
"2018.07.26 10:35:06:9229: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result",
"2018.07.26 10:35:07:1229: c0c2311a-b509-4e6e-a236-80e2d86f2647 - Client Successfully Retrieved Session",
"2018.07.26 10:35:07:1429: 4d50b064-d269-4256-a187-82a3f9402735 - End Session Requested - Thread started",
"2018.07.26 10:35:06:9019: DAIW - New Session Requested... Success (Start Session Thread Started)",
"2018.07.26 10:35:07:1219: DAIW - Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)"

在这种情况下,日期已接管。但我需要会话 ID 保持在一起。

有人可以帮我解决这个问题吗?

这是一个 tropos 日志的示例(我忽略了数据类型,它只是向您展示它如何与字符串日志相关联)

var logString = "2018.07.26 10:35:06:7889: 4d50b064-d269-4256-a187-82a3f9402735 - Client successfully got the transaction result";
var log = new TroposLog();
log.Created = "2018.07.26 10:35:06:7889";
log.SessionId = "4d50b064-d269-4256-a187-82a3f9402735";
log.Message = "Client successfully got the transaction result";

上面的日志,没有UserName或者ActionName;

var logString = "2018.07.26 10:35:07:1219: DAIW - Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)";
var log = new TroposLog();
log.Created = "2018.07.26 10:35:07:1219";
log.SessionId = "4d50b064-d269-4256-a187-82a3f9402735";
log.Message = "Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)";
log.UserName= "DAIW";

这个没有ActionName。最后:

var logString = "2018.07.26 10:35:06:9169: 4d50b064-d269-4256-a187-82a3f9402735 - Run Transaction Thread (SOCS)... Success";
var log = new TroposLog();
log.Created = "2018.07.26 10:35:06:9169";
log.SessionId = "4d50b064-d269-4256-a187-82a3f9402735";
log.Message = "Run Transaction Thread (SOCS)... Success";
log.ActionName= "SOCS";

这个没有UserName。 我希望这有助于澄清

【问题讨论】:

标签: c# linq sorting


【解决方案1】:

试试:

troposLogs.OrderBy(m => m.UserName == null).ThenBy(m => m.UserName)

所以UserName == null 是true,UserName != null 是false,bool 值的顺序是false, true。

您的错误是您首先按UserName 订购,然后按UserName "is null"...但是第二次订购是无用的(因为按 UserName 订购已经订购了将null 和not null )。你必须做相反的事情(就像我做的那样)。

测试:

var troposLogs = new List<TroposLog>();

var log = new TroposLog();
log.Created = DateTime.ParseExact("2018.07.26 10:35:06:7889", @"yyyy\.MM\.dd HH\:mm\:ss\:ffff", CultureInfo.InvariantCulture);
log.SessionId = "4d50b064-d269-4256-a187-82a3f9402735";
log.Message = "Client successfully got the transaction result";
troposLogs.Add(log);

log = new TroposLog();
log.Created = DateTime.ParseExact("2018.07.26 10:35:07:1219", @"yyyy\.MM\.dd HH\:mm\:ss\:ffff", CultureInfo.InvariantCulture);
log.SessionId = "4d50b064-d269-4256-a187-82a3f9402735";
log.Message = "Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)";
log.UserName = "DAIW";
troposLogs.Add(log);

log = new TroposLog();
log.Created = DateTime.ParseExact("2018.07.26 10:35:06:9169", @"yyyy\.MM\.dd HH\:mm\:ss\:ffff", CultureInfo.InvariantCulture);
log.SessionId = "4d50b064-d269-4256-a187-82a3f9402735";
log.Message = "Run Transaction Thread (SOCS)... Success";
log.ActionName = "SOCS";
troposLogs.Add(log);

var ordered = troposLogs.OrderBy(m => m.UserName == null)
            .ThenBy(m => m.UserName)
            .ThenBy(m => m.SessionId)
            .ThenBy(m => m.Created)
            .ToArray();

【讨论】:

  • 我也试过了,但它仍然没有给出正确的顺序。我已经更新了我上面的问题以显示结果
  • @r3plica 更新答案
【解决方案2】:

您真正想要的是按 SessionId 对日志进行分组,然后按日期对每个组进行排序(我认为),这样您就可以试试这个:

        var troposLogs = new TroposLog[]
        {
            new TroposLog
            {
                Created = DateTime.Now, 
                UserName = null,
                SessionId = "4d50b064-d269-4256-a187-82a3f9402735",
                ActionName = null,
                Message = "Client successfully got the transaction result"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = null,
                SessionId = "4d50b064-d269-4256-a187-82a3f9402735",
                ActionName = "SOCS",
                Message = "Run Transaction Requested (SOCS)... Success"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = "DAIW",
                SessionId = "c0c2311a-b509-4e6e-a236-80e2d86f2647",
                ActionName = null,
                Message = "New Session Requested... Success (Start Session Thread Started)"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = null,
                SessionId = "4d50b064-d269-4256-a187-82a3f9402735",
                ActionName = "SOCS",
                Message = "Run Transaction Thread (SOCS)... Success"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = null,
                SessionId = "4d50b064-d269-4256-a187-82a3f9402735",
                ActionName = null,
                Message = "Client successfully got the transaction result"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = "DAIW",
                SessionId = "c0c2311a-b509-4e6e-a236-80e2d86f2647",
                ActionName = null,
                Message = "Start Session ThreadSuccess (c0c2311a-b509-4e6e-a236-80e2d86f2647)"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = null,
                SessionId = "c0c2311a-b509-4e6e-a236-80e2d86f2647",
                ActionName = null,
                Message = "Client Successfully Retrieved Session"
            },
            new TroposLog
            {
                Created = DateTime.Now,
                UserName = null,
                SessionId = "4d50b064-d269-4256-a187-82a3f9402735",
                ActionName = "",
                Message = "End Session Requested - Thread started"
            },
        };

        var orderedLogs = troposLogs.OrderBy(l => l.Created) // Just in case
                                    .GroupBy(l => l.SessionId)
                                    .OrderBy(g => g.FirstOrDefault().Created)
                                    .SelectMany(g => g)
                                    .ToList();

注意:要使其正常工作,您需要在填充模型时为所有日志条目分配正确的 sessionId,例如'DAIW' 用户的所有日志都应该有 sessionId 'c0c2311a-b509-4e6e-a236-80e2d86f2647' 根据您的输入数据,这是正确的(这应该没什么大不了的)

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 2011-06-28
    • 2013-09-12
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多