Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
分层父子关系数据中仅父级上的C#LINQ Orderby_C#_Linq - Fatal编程技术网

分层父子关系数据中仅父级上的C#LINQ Orderby

分层父子关系数据中仅父级上的C#LINQ Orderby,c#,linq,C#,Linq,我在LINQ有一个有趣的问题,我不知道如何解决它。下面是我的数据 我有一个发送对象列表(list),其中发送对象具有以下属性 public class Send { public string messageName { get; set; } public string Port { get; set; } public string Type { get; set; } } 其中端口可以是PortA、PortB等。类型只能是“接收”或“发送”,

我在LINQ有一个有趣的问题,我不知道如何解决它。下面是我的数据

我有一个发送对象列表(
list
),其中发送对象具有以下属性

public class Send
{   
    public string messageName { get; set; }
    public string Port { get; set; }        
    public string Type { get; set; }
}
其中端口可以是
PortA、PortB
等。类型只能是
“接收”
“发送”
,并且可以是messageName

0_firstmessage
1_secondmessage
2_thirdmessage
messageName始终在开头0,1,2…处有一个标识符

我当前的列表包含如下数据。数据中需要注意的几点

  • 我的数据已经按照端口进行了排序。所以,PortA数据来了 首先是PortB
  • “接收”类型的每条消息后面都有0条或N条发送消息组
  • 每个发送消息始终有一个父接收
  • 我的数据:

    MESSAGENAME, PORT  , TYPE  
        - 0_message , PortA , receive
           - 1_message , PortA , transmit
           - 3_message , PortA , transmit
           - 7_message , PortA , transmit
        - 8_message , PortA , receive
           - 9_message , PortA , transmit
    
        - 2_message , PortB , receive
        - 4_message , PortB , receive
           - 5_message , PortB , transmit
           - 6_message , PortB , transmit
        - 10_message, PortB , receive
           - 11_message , PortB , transmit
    
    我的最终输出应该是这样的

     MESSAGENAME, PORT  , TYPE  
    - 0_message , PortA , receive
       - 1_message , PortA , transmit
       - 3_message , PortA , transmit
       - 7_message , PortA , transmit
    - 2_message , PortB , receive
    - 4_message , PortB , receive
       - 5_message , PortB , transmit
       - 6_message , PortB , transmit
    - 8_message , PortA , receive
       - 9_message , PortA , transmit
    - 10_message, PortB , receive
       - 11_message , PortB , transmit
    
    我只想根据“接收”类型的消息的消息名称进行订购。子“传输”消息应保持完整

    我在网上搜索了很多,但我不知道如何编写这个LINQ查询

    这里有一个例子:你可以在这里玩。 请尝试下面的代码

        public class Send : IComparable<Send>
        {
            public string messageName { get; set; }
            public string Port { get; set; }
            public string Type { get; set; }
    
    
            public int CompareTo(Send other)
            {
                int results = 0;
                if (this.messageName != other.messageName)
                {
                    results = this.messageName.CompareTo(other.messageName);
                }
                else
                {
                    if (this.Port != other.Port)
                    {
                        results = this.Port.CompareTo(other.Port);
                    }
                    else
                    {
                        results = this.Type.CompareTo(other.Type);
                    }
                }
                return results;
            }
        }
    
    公共类发送:i可比较
    {
    公共字符串messageName{get;set;}
    公共字符串端口{get;set;}
    公共字符串类型{get;set;}
    公共整数比较(发送其他)
    {
    int结果=0;
    if(this.messageName!=其他.messageName)
    {
    结果=this.messageName.CompareTo(其他.messageName);
    }
    其他的
    {
    if(this.Port!=其他.Port)
    {
    结果=此.Port.CompareTo(其他.Port);
    }
    其他的
    {
    结果=此.Type.CompareTo(其他.Type);
    }
    }
    返回结果;
    }
    }
    
    我有一个解决方案,假设您首先接收
    receive
    ,然后是
    transmit
    类型的消息

    int gid=0;
    var results = messages.Select(m => new 
                         {                                 // Rank each message 
                            m.Type.Equals("Receive", StringComparison.InvariantCultureIgnoreCase ) ? ++gid: gid, 
                            message=m 
                         })
        .GroupBy(g=>g.groupid) // Group them on Rank
        .OrderBy(g=>int.Parse(g.First().message.messageName.Split('_')[0]))  // apply Sort
        .SelectMany(c=>c.Select(x=>x.message)) // flatten structure .
        .ToList() ; 
    

    检查工作状态

    我希望此LINQ可以帮助您:

    var a = mylist.OrderBy(x => x.MESSAGENAME).Where(y => y.TYPE == "receive")
                          .Concat(mylist.Where(z => z.TYPE!= "receive"));
    

    因此,您将获得IEnumerable,其中第一个按消息类型发送,第二个按消息类型发送,其余的发送都是无序的。

    我还有一个建议给您。您可以添加一个字典,并将您的列表放在key-will-yoursend with message type=“receive”的位置,然后您可以简单地按键订购字典。检查此代码:

            List<Send> messages = new List<Send>();
    
        messages.Add(new Send() {messageName ="0_message" , Port = "PortA", Type="Receive" });
        messages.Add(new Send() {messageName ="1_message" , Port = "PortA", Type="transmit" });
        messages.Add(new Send() {messageName ="3_message" , Port = "PortA", Type="transmit" });
        messages.Add(new Send() {messageName ="7_message" , Port = "PortA", Type="transmit" });
        messages.Add(new Send() {messageName ="8_message" , Port = "PortA", Type="Receive" });
        messages.Add(new Send() {messageName ="9_message" , Port = "PortA", Type="transmit" });
        messages.Add(new Send() {messageName ="2_message" , Port = "PortB", Type="Receive" });
        messages.Add(new Send() {messageName ="4_message" , Port = "PortB", Type="Receive" });
        messages.Add(new Send() {messageName ="5_message" , Port = "PortB", Type="transmit" });
        messages.Add(new Send() {messageName ="6_message" , Port = "PortB", Type="transmit" });
        messages.Add(new Send() {messageName ="10_message" , Port = "PortB", Type="Receive" });
        messages.Add(new Send() {messageName ="11_message" , Port = "PortB", Type="transmit" });
    
    
         Dictionary<Send, List<Send>> myDict = new Dictionary<Send, List<Send>>();
            List<Send> mylist2 = new List<Send>();
            Send messagename = new Send();
            int i = 0;
    
    
            foreach (Send s in messages)
            {
                if (s.Type == "Receive" || s.Type == "receive")
                {
                    if (i != 0)
                    {
                        myDict.Add(messagename, mylist2);
                    }
                    messagename = s;
                    mylist2 = new List<Send>();
                }
                else
                {
                    mylist2.Add(s);
                }
    
                if(i== messages.Count()-1)
                {
                    myDict.Add(messagename, mylist2);
                }
    
                i++;
            }
    
            var q = myDict.OrderBy(x => int.Parse(x.Key.messageName.Split('_')[0]));
    
    List messages=newlist();
    添加(newsend(){messageName=“0_message”,Port=“PortA”,Type=“Receive”});
    添加(newsend(){messageName=“1_message”,Port=“PortA”,Type=“transmit”});
    添加(newsend(){messageName=“3_message”,Port=“PortA”,Type=“transmit”});
    添加(newsend(){messageName=“7_message”,Port=“PortA”,Type=“transmit”});
    添加(newsend(){messageName=“8_message”,Port=“PortA”,Type=“Receive”});
    添加(newsend(){messageName=“9_message”,Port=“PortA”,Type=“transmit”});
    添加(newsend(){messageName=“2_message”,Port=“PortB”,Type=“Receive”});
    添加(newsend(){messageName=“4_message”,Port=“PortB”,Type=“Receive”});
    添加(newsend(){messageName=“5_message”,Port=“PortB”,Type=“transmit”});
    添加(newsend(){messageName=“6_message”,Port=“PortB”,Type=“transmit”});
    添加(newsend(){messageName=“10_message”,Port=“PortB”,Type=“Receive”});
    添加(newsend(){messageName=“11_message”,Port=“PortB”,Type=“transmit”});
    Dictionary myDict=新字典();
    List mylist2=新列表();
    Send messagename=new Send();
    int i=0;
    foreach(在消息中发送消息)
    {
    如果(s.Type==“接收”| | s.Type==“接收”)
    {
    如果(i!=0)
    {
    myDict.Add(messagename,mylist2);
    }
    messagename=s;
    mylist2=新列表();
    }
    其他的
    {
    mylist2.添加(s);
    }
    if(i==messages.Count()-1)
    {
    myDict.Add(messagename,mylist2);
    }
    i++;
    }
    var q=myDict.OrderBy(x=>int.Parse(x.Key.messageName.Split(“”“)[0]);
    
    如果需要,可以将字典转换回列表:

            List<Send> newlist = new List<Send>();
    
            foreach (KeyValuePair<Send, List<Send>> k in q)
            {
                newlist.Add(k.Key);
    
                foreach (Send s in k.Value)
                {
                    newlist.Add(s);
                }
            }
    
    List newlist=newlist();
    foreach(q中的KeyValuePair k)
    {
    newlist.Add(k.Key);
    foreach(以k值发送s)
    {
    新列表。添加(s);
    }
    }
    
    向类添加属性
    公共发送父对象{get;set;}
    (可能还有反向子对象集合)。确定所有孩子的父母。然后,在没有父对象的情况下,您应该能够简单地按
    messageName
    排序。对于每个家长,然后打印孩子。查看我的答案,代码将不起作用。我认为您需要将发送消息作为接收消息的子消息,这样当您对发送消息进行排序时,将保留同一接收消息。我不理解这一点。这与我的问题有什么关系。请添加一些说明。需要使用IComparable进行自定义比较。OrderBy将使用类的CompareTo()方法。因此,您可以只使用OrderBy,CompareTo()方法将进行比较。它无法正常工作。我已经用我在问题描述中提到的完整数据更新了您的示例。正如您在输出中所看到的,8_message应该比10_messageAhh先出现。。我明白了,让我来修正。修正了,现在检查。谢谢你修改你的例子。但是您的查询以原始格式输出数据。我想要最终输出中的数据(如问题中提到的)。我更新了fiddler,因为您的数据中有“接收”而不是“接收”。解决方案