Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.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将存储在一维数组中的记录分组_C#_Sql_Arrays_Linq - Fatal编程技术网

C# 使用LINQ将存储在一维数组中的记录分组

C# 使用LINQ将存储在一维数组中的记录分组,c#,sql,arrays,linq,C#,Sql,Arrays,Linq,我有一种情况,我从数据库中获取数据的方式是,所有数据都存储在一维数组中。 例如: User table: UserId, Name Group table: GroupId, Name UserGroup table: UserId, GroupId 通过连接这些表,我获得了以下形式的数组: result[0] = "1" // user id result[1] = "John Doe" // user name result[2] = "121" // group id result[3]

我有一种情况,我从数据库中获取数据的方式是,所有数据都存储在一维数组中。
例如:

User table: UserId, Name
Group table: GroupId, Name
UserGroup table: UserId, GroupId
通过连接这些表,我获得了以下形式的数组:

result[0] = "1" // user id
result[1] = "John Doe" // user name
result[2] = "121" // group id
result[3] = "SomeGroup" // group name
result[4] = "1" // user id
result[5] = "John Doe" // user name
result[6] = "2135" // group id
result[7] = "SomeOtherGroup" // group name
我知道这不是一个保存数据的好方法,但是这些数据是从我不允许更改的其他代码中获得的,所以我必须处理它。

我的问题是:

  • 是否可以使用LINQ来解析此数组并将数据放入我自己的对象(其中包含Groups集合的用户类)中
  • 如果不是LINQ,还有什么最好的处理方法

  • 您可以使用循环之类的基本结构来实现:

    void Main()
    {
        var result = new string[] {"1","John Doe","2","Joes Group","3","Jack Daniel","4","Jacks Group","5","Foo Bar","6","FooBar Group",};
        List<Person> personList = new List<Person>();
        List<Group> groupList = new List<Group>();
    
        for(int i = 0; i < result.Length; i+=2) 
        {
            i = i + 2;
            //check if group does not already exist
            groupList.Add(new Group() {Name = result[i+1]});
        }
    
        for(int i = 0; i < result.Length; i+=2)
        {
            //check if person exists.
            //if person only add group to person personList.Where(x => x.Name ==result[i+1])....
            personList.Add(new Person() { Id = int.Parse(result[i]), 
                                          Name = result[i+1],
                                          Groups = new List<Group>()
                                          {
                                            groupList.FirstOrDefault (l => l.Name == result[i+3])
                                          }
                                        });
            i = i+2;    
        }
    
        personList.Dump();
    }
    
    public class Person
    {
        public Person()
        {
            Groups = new List<Group>();
        }
        public int Id { get; set; }
        public string Name { get; set; }
        public List<Group> Groups { get; set; }
    
    }
    
    public class Group
    {
        public string Name { get; set; }
    }
    // Define other methods and classes here
    
    void Main()
    {
    var result=新字符串[]{“1”、“John Doe”、“2”、“Joes组”、“3”、“Jack Daniel”、“4”、“Jacks组”、“5”、“Foo Bar”、“6”、“FooBar组”、};
    List personList=新列表();
    List groupList=新列表();
    对于(int i=0;ix.Name==result[i+1])。。。。
    添加(newPerson(){Id=int.Parse(结果[i]),
    名称=结果[i+1],
    组=新列表()
    {
    groupList.FirstOrDefault(l=>l.Name==result[i+3])
    }
    });
    i=i+2;
    }
    personList.Dump();
    }
    公共阶层人士
    {
    公众人士()
    {
    组=新列表();
    }
    公共int Id{get;set;}
    公共字符串名称{get;set;}
    公共列表组{get;set;}
    }
    公共课组
    {
    公共字符串名称{get;set;}
    }
    //在此处定义其他方法和类
    
    输出:

    请注意:此代码不包含任何验证逻辑或重复检查。你必须自己完成这个。
    但在您实现类似的功能之前,我宁愿改变您获取数据的方式。这样你就可以解决问题的根源,而不是症状。

    我认为没有必要

    //一些班级

        public class Result
        {    
            public string UserId {get;set;}
            public string UserName {get;set;}
            public string GroupId {get;set;}
            public string GroupName {get;set;}
            public string UserGroupUserId {get;set;}
            public string UserGroupUserName {get;set;}
            public string UserGroupId {get;set;}
            public string UserGroupGroupId {get;set;}
    
        }
    
    //您的阵列

        private void Form1_Load(object sender, EventArgs e)
         {
            string[] result = new string[8];
            result[0] = "1";
            result[1] = "John Doe";
            result[2] = "121";
            result[3] = "SomeGroup";
            result[4] = "1";
            result[5] = "John Doe";
            result[6] = "2135";
            result[7] = "SomeOtherGroup";
    
    
    
            Result r = CastResult(result);
    
    
        }
    
    //将数组简单转换为某种类型

        public Result CastResult(string[] array)
        {
            return new Result() { UserId=array[0], UserName=array[1], GroupId=array[2], GroupName=array[3], UserGroupUserId=array[4], UserGroupUserName=array[5] , UserGroupId=array[6], UserGroupGroupId=array[7] };
        }
    
    纯linq表达式:

    int i = 0;
    var objects = result.GroupBy(x => Math.Floor(i++ / 4.0))
                .Select(g => new { id =g.ElementAt(0), name = g.ElementAt(1), gId= g.ElementAt(2), group = g.ElementAt(3)})
                .GroupBy(x=>new {x.id, x.name}, x=>new {x.gId, x.group})
                .Select(y=>new {y.Key, groups = y.ToList()});
    
    • 在第一个
      GroupBy
      I组中,使用一个floor和一个临时变量生成4个元素子集
    • 接下来的
      选择
      将生成的数组放在匿名类型中,以便在接下来的步骤中更好地使用
    • 下一个
      GroupBy
      用于按员工对条目进行分组。键将是员工,值将是相应的组
    • 最后,lase
      Select
      用于将
      GroupBy
      结果设置为更好的形状。我选择将结果放在另一个匿名类型中,但您可以在这里实例化自定义对象,并使用花括号构造函数将值放在正确的字段中

    如果您的逻辑依赖于索引,那么LINQ很少是正确的工具。与普通循环相比,它导致可读性、可维护性、高效性和健壮性较差的代码

    我将使用如下内容创建两个表示多对多关系的字典。请注意-循环的
    ,它在每次迭代中递增4,因为这似乎是用户组-“package”:


    因此,一个用户可以属于多个组(在本例中,它将重复该用户)。所有用户所属的组是否也对每个用户重复?这是多对多关系。一个用户可以属于多个组,一个组可以包含多个用户。那么如何区分用户和组?可能仅通过索引和重复模式我只知道查询结果显示多少列。我知道包含此结果数组的对象的RowCount和ColumnCount属性。例如,要获取我使用的第i条记录的组名:result[i*ColumnCount+3]。您需要添加
    inti=0。没有它就无法编译你的解决方案太棒了!非常感谢。你能耐心地一步一步地解释它是如何工作的吗?我真的不明白会发生什么。是的,我会修改我的答案。有十几个原因导致此查询可能失败;-)@我认识我的朋友。我看到两个主要问题:结果。长度%4!=0和result.Any(x=>x==null)。这两种情况都可以通过一些预先检查来避免:P
    
    var userIdGroups = new Dictionary<int, HashSet<Group>>();
    var groupIdUsers = new Dictionary<int, HashSet<User>>();
    
    for(int i = 0; i < result.Length; i += 4)
    {
        int id;
        if(int.TryParse(result[i], out id))
        {
            string name = result.ElementAtOrDefault(i + 1);
            if(name == null)
                continue; // end, invalid data
    
            User user = new User{ UserId = id, Name = name };
            string groupID = result.ElementAtOrDefault(i + 2);
            if(!int.TryParse(groupID, out id))
                continue; // end, invalid data
    
            name = result.ElementAtOrDefault(i + 3);
            if(name == null)
                continue; // end, invalid data
    
            Group group = new Group{ GroupId = id, Name = name };
            HashSet<Group> userGroups;
            HashSet<User> groupUsers;
            if (userIdGroups.TryGetValue(user.UserId, out userGroups))
                userGroups.Add(group);
            else
                userIdGroups.Add(user.UserId, new HashSet<Group>{ group });
    
            if (groupIdUsers.TryGetValue(group.GroupId, out groupUsers))
                groupUsers.Add(user);
            else
                groupIdUsers.Add(group.GroupId, new HashSet<User> { user });
        }
    }
    
    class User
    {
        public int UserId { get; set; }
        public string Name { get; set; }
    
        public override bool Equals(object obj)
        {
            User u2 = obj as User;
            if (u2 == null) return false;
            return UserId == u2.UserId;
        }
        public override int GetHashCode()
        {
            return UserId;
        }
    }
    class Group
    {
        public int GroupId { get; set; }
        public string Name { get; set; }
    
        public override bool Equals(object obj)
        {
            Group g2 = obj as Group;
            if (g2 == null) return false;
            return GroupId == g2.GroupId;
        }
        public override int GetHashCode()
        {
            return GroupId;
        }
    }