将两个Dictionary <string,list <model =“” >>类型的泛型组合到另一个相同类型的

时间:2019-01-30 15:27:43

标签: c# linq generics

我有两个Dictionary<string, List<Person>>类型的泛型,其中Person是:

Person {
   string FirstName;
   string LastName; 
   List<string> Aliases;
   string Address; 
}

泛型之一是“默认”,其中仅填写名字和姓氏。为简单起见,我将其称为“默认字典” ...第二个字典(数据库字典)中填充了从数据库返回的值呼叫。这两个词典的关键字都是person对象中的“ FirstName”。

某些条件是:

  • 默认字典在列表中具有“人”对象的正确顺序...它们不是按字母顺序排列或类似的内容
  • 并非默认列表中的所有“ Person”对象也都将在数据库列表中(尽管db列表中的person对象在默认列表中始终具有匹配项)
  • 虽然绝对有更好的方法来表示此数据...字典类型必须保持原样,因为我将它们传递给使用foreach循环(嵌套表)的视图,其中键是主表列表是键下方的子表的行

我需要做的是使用从db返回的数据填写每个关键字的默认字典列表的地址和别名列表。

我已经能够正确格式化默认字典和db字典,并使用正确的数据填充(尽管db字典中的列表顺序不正确)...我也能够“过滤”将默认字典转换为仅包含db字典(已过滤字典)中也存在的键的新字典。

我遇到的问题是用从db返回的每个对象的地址和别名列表填充Person对象...我不能只替换列表,因为我需要保留person对象的顺序列表...这是我尝试的最后一件事的一些代码片段(将来自数据库的响应放入称为“ responseList”的所有人员对象的列表中)...

    Dictionary<string, List<Person>> filteredDictionary = defaultDictionary.Where(x => firstNameList.Contains(x.Key)).ToDictionary(x => x.Key, y => y.Value);

    foreach (var entry in filteredDictionary)
    {
        var current = entry.Value.ToList();

        current.ForEach(x => responseList.Any(y => y.FirstName == x.FirstName));
        current.ForEach(x => x.Address = responseList.Select(y => y.Address));

    } 

我知道使用LINQ ...最好只是创建一个新词典而不是修改现有词典...但是我不确定如何将这些信息放入一个新的词典中以保留列表中的人物订购...

任何帮助将不胜感激……我在这个问题上停留了一段时间。

1 个答案:

答案 0 :(得分:1)

起初,您应该知道Dictionary<TKey, TValue>不能确保特定顺序:

  

出于枚举目的,字典中的每个项目都被视为代表值及其键的KeyValuePair结构。物品的退还顺序是不确定的。

尽管如此,当前实现似乎以与给定值相同的顺序返回值。但是他们并不能保证这一点。如果您需要特定的订单,则应使用SortedDictionary<TKey, TValue>并提供所需的比较器。

给出这些信息后,这里有一个示例,说明如何使用数据库字典中的值更新默认字典。

// Create some sample data, we can use
var persons = Enumerable
    .Range(1, 10)
    .Select(i => new Person
    {
        FirstName = $"FirstName {i}",
        LastName = Guid.NewGuid().ToString(),
        Address = $"Address {i}",
        Aliases = Enumerable
            .Range(i * 100, i)
            .Select(j => $"Alias {i} - {j}")
            .ToList()
    })
    .ToList();

// Create the default dict, (hopefully) ordered by Firstname
var defaultDict = persons.ToDictionary(
    person => person.FirstName,
    person => new Person
    {
        FirstName = person.FirstName,
        LastName = person.LastName
    });

// Create the default dict, (hopefully) ordered by Lastname
var dbDict = persons
    .OrderBy(person => person.LastName)
    .ToDictionary(person => person.FirstName);

Console.WriteLine("Default dictionary");
foreach (var person in defaultDict)
{
    Console.WriteLine($"{person.Value.FirstName} {person.Value.LastName} {person.Value.Address ?? "No address" }");
}

Console.WriteLine();
Console.WriteLine("DB dictionary");
foreach (var person in dbDict)
{
    Console.WriteLine($"{person.Value.FirstName} {person.Value.LastName} {person.Value.Address ?? "No address" }");
}

// Iterate over the db entries and update all default entries
foreach (var item in dbDict)
{
    if(defaultDict.TryGetValue(item.Key, out Person defaultPerson))
    {
        defaultPerson.Address = item.Value.Address;
        defaultPerson.Aliases = item.Value.Aliases.ToList();
    }
}

// Show updated default dictionary
Console.WriteLine();
Console.WriteLine("Updated default dictionary");
foreach (var person in defaultDict)
{
    Console.WriteLine($"{person.Value.FirstName} {person.Value.LastName} {person.Value.Address ?? "No address" }");
}