使用LINQ将复杂对象映射到字典

4

考虑以下对象:

Controller controller = new Controller()
{
    Name = "Test",
    Actions = new Action[]
    {
        new Action() { Name = "Action1", HttpCache = 300 },
        new Action() { Name = "Action2", HttpCache = 200 },
        new Action() { Name = "Action3", HttpCache = 400 }
    }
};

我该如何将这个对象映射到以下形式的字典中?
#key# -> #value#
"Test.Action1" -> 300
"Test.Action2" -> 200
"Test.Action3" -> 400

也就是说,一个 Dictionary<string, int>

我对 LINQ 解决方案很感兴趣,但我无法解决它。

我试图将每个操作映射到一个 KeyValuePair,但我不知道如何获取每个操作的父控制器的 Name 属性。

4个回答

6

最重要的是,在lambda表达式中,控制器仍然在作用域内:

var result = controller.Actions.ToDictionary(
  a => string.Format("{0}.{1}", controller.Name, a.Name),
  a => a.HttpCache);

不错的解决方案,但首先请检查列表中所有操作名称是否唯一 :) - Marek Woźniak

1
LINQ的方法是使用Select方法将Actions列表投影为一个字典。由于您正在调用它的Controller实例,因此还可以访问控制器的Name属性:
myController.Actions.ToDictionary(
    /* Key selector - use the controller instance + action */
    action => myController.Name + "." + action.Name, 
    /* Value selector - just the action */
    action => action.HttpCache);

如果您想从多个控制器创建一个大字典,可以使用SelectMany将每个控制器的项目投影到Controller+Action列表中,然后将该列表转换为字典。
var namesAndValues = 
    controllers.SelectMany(controller =>
        controller.Actions.Select(action =>
            { 
              Name = controller.Name + "." + action.Name,
              HttpCache = action.HttpCache
            }));
var dict = namesAndValues.ToDictionary(nav => nav.Name, nav => nav.HttpCache); 

1
你可以尝试这个:

var dico = controller.Actions
                     .ToDictionary(a => $"{controller.Name}.{a.Name}", 
                                   a => a.HttpCache);

第一个 lambda 表达式针对字典条目的键,而第二个则针对其值。

这里两个名称之间缺少点号:.ToDictionary(a => $"{controller.Name}.{a.Name}", - 15ee8f99-57ff-4f92-890c-b56153

0
假设您有多个控制器集合,而不仅仅是示例代码中的一个controller变量,并且想要将它们所有的操作放入一个单独的字典中,那么您可以这样做:
var httpCaches = controllers.SelectMany(controller =>
    controller.Actions.Select(action =>
        new
        {
            Controller = controller,
            Action = action
        })
    )
    .ToDictionary(
        item => item.Controller.Name + "." + item.Action.Name,
        item => item.Action.HttpCache);

这适用于您的数据集设置如下的情况:

var controllers = new[] {
    new Controller()
    {
        Name = "Test1",
        Actions = new Action[] {
            new Action { Name = "Action1", HttpCache = 300 },
            new Action { Name = "Action2", HttpCache = 200 },
            new Action { Name = "Action3", HttpCache = 400 },
        }
    },
    new Controller()
    {
        Name = "Test2",
        Actions = new Action[] {
            new Action { Name = "Action1", HttpCache = 300 },
            new Action { Name = "Action2", HttpCache = 200 },
            new Action { Name = "Action3", HttpCache = 400 },
        }
    },
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接