C# Dictionary With One To Many Relationship

Dictionary With One To Many Relationship Banner Image

Introduction

While a dictionary in C# has a set structure and use cases for the one-to-one relationship. You may be wondering how you can use a dictionary or List for a one-to-many relationship with the data. There are two and possibly more ways. But I'm going to be talking about how to do it with a dictionary and a list in this article.

Can A Dictionary Have Duplicate Keys?

A dictionary can not have duplicate keys, because the keys are required to be unique. Usually, a dictionary has one to one ratio to the key and values. But in this case, we want to have one key and many values. There are a few workarounds. Let's look at the first example.

Summary Table

Analysis TypeDictionary with ListList with KeyValuePairs
Use CaseSpeed of key retrievalSorting of keys
PerformanceValue Set Approaches O(1) then lookup for Value O(1)O(N)

Dictionary and List Method

The idea behind this is to still have a quick lookup by the key values. You can add keys and values to the dictionary like the one below. This code has a class named Data which stores a master name and one of its synonyms. The name will stay the same while the synonym will be changing so this is a one-to-many relationship.

Dictionary<string,List<string>> synonymsDictionary = new Dictionary<string,List<string>>();
List<Data> dataList = new List<Data>();
dataList.Add(new Data("Euphoric", "Exultant"));//Generate Data point
dataList.Add(new Data("Euphoric", "Rapturous"));//Generate Data point
dataList.Add(new Data("Euphoric", "Thrilled"));//Generate Data point
dataList.Add(new Data("Euphoric", "Transported"));//Generate Data point
dataList.Add(new Data("Euphoric", "Delirious"));//Generate Data point

foreach (Data item in dataList)//Loop through all data points
{
    if(!synonymsDictionary.ContainsKey(item.Name))//Check if the key is in the dictionary then take appropriate action
    {
        synonymsDictionary[item.Name] = new List<string>();//If the key does not exist then add the key with a new list
        Console.WriteLine($"New List Added for name:{item.Name}");
        synonymsDictionary[item.Name].Add(item.Synonym);//Add the value to the new list
        Console.WriteLine($"Synonym Added:{item.Synonym}");
    }
    else
    {
        synonymsDictionary[item.Name].Add(item.Synonym);//If key already exists then just add to the list
        Console.WriteLine($"Synonym Added:{item.Synonym}");
    }
}

class Data
{
    public Data(string name, string synonym)
    {
        Name = name;
        this.Synonym = synonym;
    }

    public string Name { get; set; }
    public string Synonym { get; set; }
}
Code Output
New List Added for name:Euphoric
Synonym Added:Exultant
Synonym Added:Rapturous
Synonym Added:Thrilled
Synonym Added:Transported
Synonym Added:Delirious

Dictionary and List Code Example

This example code shows how you can get the values from the dictionary after they're already there. This is a dictionary where the key is the main word and the values are the synonyms.

Dictionary<string, List<string>> synonymsDictionary = new Dictionary<string, List<string>>()
{
    { "Gleeful", new List<string>{ "Joyful", "Delighted", "Ecstatic", "Elated", "Enchanted" } },
    { "Cheerful", new List<string>{ "Glad", "Pleased", "Jubilant", "Radiant", "Satisfied" } },
    { "Content", new List<string>{ "Fulfilled", "Satisfied", "Happy", "Gratified", "Pleased" } },
    { "Jovial", new List<string>{ "Merry", "Festive", "Jolly", "Convivial", "Lighthearted" } }}
};//Generate a dictionary with one key but many values

string key = "Content";
if (synonymsDictionary.TryGetValue(key, out List<string> values))//Get the list of values from the dictionary with one key
{
    foreach (string value in values)//Loop through all the values
    {
        Console.WriteLine($"value:{value}");//Print out values
    }
}
Code Output
value:Fulfilled
value:Satisfied
value:Happy
value:Gratified
value:Pleased

List Of KeyValuePairs

While the dictionary uses the KeyValuePair to store the keys and values internally. We can use the KeyValuePair class outside of the dictionary context. Instead of a lookup through the key to getting the values. We can sort this list or search through it to find the key-value pair that we want.

List Of KeyValuePairs Example Code

List<KeyValuePair<string, string>> synonymsList = new List<KeyValuePair<string, string>>()
{
    new KeyValuePair<string, string>("Large", "Big"),
    new KeyValuePair<string, string>("Large", "Huge"),
    new KeyValuePair<string, string>("Large", "Enormous"),
    new KeyValuePair<string, string>("Large", "Gigantic"),
    new KeyValuePair<string, string>("Large", "Immense"),

    new KeyValuePair<string, string>("Small", "Little"),
    new KeyValuePair<string, string>("Small", "Tiny"),
    new KeyValuePair<string, string>("Small", "Miniature"),
    new KeyValuePair<string, string>("Small", "Petite"),
    new KeyValuePair<string, string>("Small", "Diminutive"),

    new KeyValuePair<string, string>("Bright", "Radiant"),
    new KeyValuePair<string, string>("Bright", "Vibrant"),
    new KeyValuePair<string, string>("Bright", "Luminous"),
    new KeyValuePair<string, string>("Bright", "Shiny"),
    new KeyValuePair<string, string>("Bright", "Dazzling"),

    new KeyValuePair<string, string>("Dark", "Gloomy"),
    new KeyValuePair<string, string>("Dark", "Shadowy"),
    new KeyValuePair<string, string>("Dark", "Obscure"),
    new KeyValuePair<string, string>("Dark", "Dim"),
    new KeyValuePair<string, string>("Dark", "Murky"),

    new KeyValuePair<string, string>("Fast", "Quick"),
    new KeyValuePair<string, string>("Fast", "Rapid"),
    new KeyValuePair<string, string>("Fast", "Swift"),
    new KeyValuePair<string, string>("Fast", "Speedy"),
    new KeyValuePair<string, string>("Fast", "Expeditious")
};//Generate a list of KeyValuePairs

foreach (KeyValuePair<string, string> keyValuePair in synonymsList)//Loop through all the KeyValuePairs
{
    Console.WriteLine($"value:{keyValuePair.Value}");//Print out values
}
Code Output
value:Miniature
value:Petite
value:Diminutive
value:Radiant
value:Vibrant
value:Luminous
value:Shiny
value:Dazzling
value:Gloomy
value:Shadowy
value:Obscure
value:Dim
value:Murky
value:Quick
value:Rapid
value:Swift
value:Speedy
value:Expeditious

Conclusion

Having a dictionary with a key and then a list is a solid choice to solve the one key to many values problem. It has a fast lookup and usually, there are not many values to search through after that. This can help divide the data into more manageable chunks.

Using the list to store the KeyValuePairs is also an option. This allows sorting and displaying of the data in different ways or order. So you'll need to choose carefully depending on the requirements that are needed.

Know any other collections or ways to have a collection or data structure that has a one-to-many relationship? Let me know in the comments below.

Get Latest Updates