简体   繁体   English

使用Linq更新嵌套列表值?

[英]Updating nested list values with Linq?

I am trying to update a nested list in C# which looks like this 我正在尝试更新C#中的嵌套列表,如下所示

List <Users > 列出<Users >
- UserType - 用户类型
- List <UserComponents > -列出<UserComponents >
- - UserComponentKey --UserComponentKey
- - Count --计数

Here's a written example: 这是一个书面示例:
List of users: UserType = 1 用户列表:UserType = 1
UserComponents 用户组件
- UserComponentKey = XYZ -UserComponentKey = XYZ
- Count = 3 -计数= 3

UserType = 2 用户类型= 2
UserComponents 用户组件
- UserComponentKey = XYZ -UserComponentKey = XYZ
- Count = 7 -计数= 7

I need to update UserComponentKey XYZ for UserType 2 only, currently my updates are broken and updates XYZ for all user types. 我只需要为UserType 2更新UserComponentKey XYZ,当前我的更新已损坏,并且为所有用户类型更新XYZ。 Here is my current methods which do not work as they update the UserComponent count value for ALL usertypes which contain the specified component key, and not the specific usertype I am targeting. 这是我目前无法使用的方法,因为它们会更新所有包含指定组件键而不是我定位的特定用户类型的用户类型的UserComponent计数值。

CLASSES: 类:

public class Users
{
    public string UserType { get; set; }
    public List<UserComponent> UserComponents { get; set; }
}

public class UserComponent
{
    public string UserComponentKey { get; set; }
    public int Count { get; set; }
}

METHOD 1: 方法1:

Users.Where(us => us.UserType == "2")
     .First().UserComponents
     .Where(uc => uc.UserComponentKey == "XYZ")
     .First().Count = value;

METHOD 2: 方法2:

if(users.UserType == "2")
{
   foreach(var component in users.UserComponents)
   {
       switch(component.UserComponentKey)
       {
          case "XYZ":
          component.Count = value;
          break;
       }
    }
}

CODE GENERATING LIST (similar to): List UserComponents = new List(); 代码生成列表(类似于):列表UserComponents = new List();

if (Item.UserAddOn != null)
    {
        for (var i = 0; i < Item.UserAddOn.First().Count; i++)
        {
            UserComponents.Add(new UserComponent
            {
                UserComponentKey = Item.UserAddOn[i].ComponentKey,
                Count = 0
             });
         }
    }

if (Item.User != null)
    {
        for (var i = 0; i < Item.User.First().Count; i++)
        {
             Users.Add(new User()
             {
                 UserType = Item.User[i].ComponentKey,
                 Count = 0,
                 UsersComponents = UserComponents
             });
         }
     }

I have stripped out actual values etc, but hopefully someone can point me in the right direction here. 我已经删除了实际值等,但希望有人可以在这里指出正确的方向。

Thanks! 谢谢!

Your first call to First() is wrong. 您第一次调用First()是错误的。 Try it like this: 像这样尝试:

Users.Where((us) => us.UserType == "2")
     .Select((us) => us.UserComponents)
     .Where((uc) => uc.UserComponentKey == "XYZ")
     .First()
     .Count = value;

Suggestion: Why don't you make UserType an int ? 建议:为什么不将UserTypeint

May be it helps: 可能有帮助:

        List<Users> _users = new List<Users>();
        _users.Add(new Users() { UserType = "1", UserComponents = new List<UserComponent>() { new UserComponent() { Count = 0, UserComponentKey = "XYZ" } } });
        _users.Add(new Users() { UserType = "2", UserComponents = new List<UserComponent>() { new UserComponent() { Count = 2, UserComponentKey = "XYZ" } } });
        _users.Add(new Users() { UserType = "3", UserComponents = new List<UserComponent>() { new UserComponent() { Count = 5, UserComponentKey = "XYZ" } } });

        _users.Where(us => us.UserType == "2").First().UserComponents.Where(uc => uc.UserComponentKey == "XYZ").First().Count = 356;

        foreach (Users us in _users)
        {
            Console.WriteLine("UserType: " + us.UserType);
            foreach (UserComponent uc in us.UserComponents)
            {
                Console.WriteLine("Key: {0} Value: {1}", uc.UserComponentKey, uc.Count);
            }
        }

I'm missing information to write a snippet you can use so I will simply explain it. 我缺少写一个可以使用的代码段的信息,所以我将仅作解释。 An object variable is in reality a reference (a pointer, if you are familiar with C++/C) to the location where the object reside. 实际上,对象变量是对对象驻留位置的引用(如果您熟悉C ++ / C,则为指针)。 When you add an object to a list, you add it's location. 将对象添加到列表时,将添加其位置。 If you add this object to multiple list, you give the same location and therefor, editing one of them will edit all of them. 如果将此对象添加到多个列表中,则会指定相同的位置,因此,编辑其中一个将编辑所有这些位置。

var uc1 = new UserComponent { Count = 1 };
var uc2 = new UserComponent { Count = 2 };
var uc3 = new UserComponent { Count = 2 };

var u1 = new User();
var u2 = new User();

u1.UserComponents.Add(uc1);
u1.UserComponents.Add(uc2);

u2.UserComponents.Add(uc1);
u2.UserComponents.Add(uc3);

Console.Write(u1.UserComponents[0].Count); //Outputs 1
Console.Write(u1.UserComponents[1].Count); //Outputs 2
Console.Write(u2.UserComponents[0].Count); //Outputs 1
Console.Write(u2.UserComponents[1].Count); //Outputs 2

u2.UserComponents[0].Count = 5;
u2.UserComponents[1].Count = 6;

Console.Write(u1.UserComponents[0].Count); //Outputs 5
Console.Write(u1.UserComponents[1].Count); //Outputs 6
Console.Write(u2.UserComponents[0].Count); //Outputs 5
Console.Write(u2.UserComponents[1].Count); //Outputs 2

So your code to change values is fine, but when you build up your list, you need to create distinct UserComponents if they are not linked together. 因此,您可以使用代码来更改值,但是在建立列表时,如果未将它们链接在一起,则需要创建不同的UserComponent。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM