C# - Retrieve data from Database and store in 2 dimension dictionary? - c#

Hello I try to do something like PHP thing that is retrieve data from database and store in 2 dimension collection (Dictionary)
I'm not sure I write it correctly or not.
Let's say my database table and expected structure result look like this (See the screenshot)
Click to see screenshot
public ActionResult ShowBook()
{
var books = from v in db.Books
select v;
Dictionary<string, Dictionary<string, string>> test = new Dictionary<string, Dictionary<string, string>>();
foreach (var item in books)
{
test[item.Book_Type_ID][item.Author_ID] = item.Book_Name;
}
return .....
}
But I has this error
System.Collections.Generic.KeyNotFoundException: 'The given key was not present in the dictionary.'
How could I do?

The problem is you have to initialize each inner Dictionary<string, string> when assigning a new key to your outer dictionary. Typically this means checking if this key exists, and if not, creating the object:
foreach (var item in books)
{
if(!test.ContainsKey(item.Book_Type_ID))
{
test[item.Book_Type_ID] = new Dictionary<string, string>();
}
//now we are sure it exists, add it
test[item.Book_Type_ID][item.Author_ID] = item.Book_Name;
}

The dictionary is 2-dimensional. When you initialize it
Dictionary<string, Dictionary<string, string>> test = new Dictionary<string, Dictionary<string, string>>();
The first dimension is initialized, but not the second - i.e. test is an empty dictionary. So when you try to add a book title to a second-dimension dictionary, there isn't a dictionary for it to be added to yet. You need to check this condition first, and create an entry if it doesn't already exist:
var books = from v in db.Books select v;
Dictionary<string, Dictionary<string, string>> test = new Dictionary<string, Dictionary<string, string>>();
foreach (var item in books)
{
if (!test.ContainsKey(item.Book_Type_ID))
test[item.Book_Type_ID] = new Dictionary<string, string>();
test[item.Book_Type_ID][item.Author_ID] = item.Book_Name;
}

Related

Is it possible to store a KeyValuePair of a dictionary without the use of a foreach loop?

The syntax for iterating over a dictionary with a foreach loop is:
foreach (KeyValuePair<key, value> item in dictionary)
Inside the foreach loop the key is accessed with item.key and the value with item.value.
This got me thinking, can this be used without the use of a foreach loop as a convenient (although niche) way to represent a specific dictionary pair?
I am not looking for some weird work arounds, like running a foreach loop and saving the KeyValuePair into a variable once the target key is reached, because at this point it would be more convenient to just use 2 variables.
Like this
var dic = new Dictionary<string, int>();
dic["a"] = 42;
KeyValuePair<string, int> keyVal;
foreach(var kv in dic) {
keyVal = kv; << gets the last entry from the dictioanry
}
Note that the dictionary does not store KeyValuePairs, it creates one for the enumeration, so the simple thing to do is this (because we are not expensively recreating something)
var dic = new Dictionary<string, int>();
dic["a"] = 42;
KeyValuePair<string, int> keyVal = new KeyValuePair<string, int>("a", dic["a"]);
this is more efficient than the (neat) LINQ Sinlge method
The IDictionary<TKey, TValue> interface implements IEnumerable<KeyValuePair<TKey,TValue>>. This means you can simply use Single() to get the entry you want.
IDictionary<string, int> dict = ...;
KeyValuePair<string, int> entry = dict.Single(it => it.Key == "yourKey");
try this
var dict = new Dictionary<string, string>() {
{"hi","Hello World!"},
{"adieu","Goodby"}
};
string hi = dict["hi"]; //Hello World!
or if you want a list
List<KeyValuePair<string,string>> list = dict.ToList();
result
[{"Key":"hi","Value":"Hello World!"},{"Key":"adieu","Value":"Goodby"}]

How to compare two dictionaries in C#?

There are different count and different order of dictionaries
If the key of list A and list B match, I would like to bring the value of list B and modify the value of list A.
Sample Code :
public static List<Dictionary<string, string>> ListDicOne = new List<Dictionary<string, string>>();
public static List<Dictionary<string, string>> ListDicTwo = new List<Dictionary<string, string>>();
(...)
ListDicOne[0].Add("ABCD", ""); // empty value
ListDicOne[1].Add("ABCD", "");
ListDicOne[2].Add("EFGH", "test");
ListDicTwo[0].Add("AABC", "oooo");
ListDicTwo[1].Add("ABCD", "WOW");
ListDicTwo[2].Add("CCDD", "haha");
ListDicTwo[3].Add("CCDD", "haha");
expected result value :
// Console Write key and value of ListDicA
ABCD \t WOW
ABCD \t WOW
EFGH \t test
I will take a guess and assume you really only want to deal with two dictionaries, and not two lists of many one-item dictionaries, which would not make any sense at all.
First, the dictionaries should be declared like this (I also assume they don't have to be public):
private static Dictionary<string, string> ListDicOne = new Dictionary<string, string>();
private static Dictionary<string, string> ListDicTwo = new Dictionary<string, string>();
And then, the usage could be like this:
ListDicOne.Add("AABC", ""); // I changed the key, they must be unique
ListDicOne.Add("ABCD", "");
ListDicOne.Add("EFGH", "test");
ListDicTwo.Add("AABC", "oooo");
ListDicTwo.Add("ABCD", "WOW");
ListDicTwo.Add("CCDD", "haha");
ListDicTwo.Add("CCDE", "haha"); // I changed the key, they must be unique
foreach (var item in ListDicTwo)
{
if (ListDicOne.ContainsKey(item.Key))
ListDicOne[item.Key] = ListDicTwo[item.Key];
}
The final state of ListDicOne is:
("AABC", "oooo")
("ABCD", "WOW")
("EFGH", "test")
I hope you find this clarifying and useful.
** Update **
Considering a string-string list with non-unique keys:
private static List<Tuple<string, string>> ListOne = new List<Tuple<string, string>>();
private static List<Tuple<string, string>> ListTwo = new List<Tuple<string, string>>();
(...)
ListOne.Add(Tuple.Create("ABCD", ""));
ListOne.Add(Tuple.Create("ABCD", ""));
ListOne.Add(Tuple.Create("EFGH", "test"));
ListTwo.Add(Tuple.Create("AABC", "oooo"));
ListTwo.Add(Tuple.Create("ABCD", "WOW"));
ListTwo.Add(Tuple.Create("CCDD", "haha"));
ListTwo.Add(Tuple.Create("CCDD", "haha"));
foreach (var l2item in ListTwo)
{
for (int i = 0; i < ListOne.Count; i++)
{
if (ListOne[i].Item1 == l2item.Item1)
ListOne[i] = Tuple.Create(l2item.Item1, l2item.Item2);
}
}
Note 1: tuples are immutable, so you need to create a new one when changing Item2.
Note 2: You cannot use foreach when you need to alter the iterated list, therefore I used a for instead.
Note 3: If ListTwo happens to have a two different key-value combinations (supposedly won't happen), the second one will overwrite the first.
This is the end result with your test values:
("ABCD", "WOW")
("ABCD", "WOW")
("EFGH", "test")

Linq on nested Dictionary

I have a dictionary of dictionary and I want to find a value from inner dictionary by Linq .
My code is:
private Dictionary<string, Dictionary<int, string>> SubCategoryDictionary = new Dictionary<string, Dictionary<int, string>>();
private Dictionary<int, string> BGA_Dictionary = new Dictionary<int, string>();
private Dictionary<int, string> Lead3D_Dictionary = new Dictionary<int, string>();
private Dictionary<int, string> Lead2D_Dictionary = new Dictionary<int, string>();
private Dictionary<int, string> Leadless_Dictionary = new Dictionary<int, string>();
private Dictionary<int, string> PIC_Dictionary = new Dictionary<int, string>();
In my constructor I have all values like this:--
BGA_Dictionary.Add(1, "Body_Measurement");
BGA_Dictionary.Add(2, "Ball_Measurement");
SubCategoryDictionary.Add("BGA", BGA_Dictionary);
Lead3D_Dictionary.Add(1, "Component_Height");
Lead3D_Dictionary.Add(2, "Rib_Measurement");
SubCategoryDictionary.Add("Package", Lead3D_Dictionary);
Lead2D_Dictionary.Add(1, "Dirt_Inspection");
Lead2D_Dictionary.Add(2, "Half_Cut_Inspection");
SubCategoryDictionary.Add("Mark", Lead2D_Dictionary);
Now I need a Lambda expression which will give me something like :
when key of SubCategoryDictionary ="Mark" and key of Lead3D_Dictionary =2 then I should get "Rib_Measurement".
I tried with following code :
string q = (from cls in SubCategoryDictionary
from s in cls.Value
where cls.Key == "Mark" && s.Key == 3
select s.Value).FirstOrDefault();
foreach (var a in q)
{
}
This above code works but I need in lambda expression. So if someone help me in formation of Lambda formation. It will be of great help.
Thanks.
I'm not sure why you ever need a lambda for accessing a dictionary by keys, but here it is:
Func<string,int,string> lambda = (k1, k2) => SubCategoryDictionary[k1][k2];
Now you can invoke it with var subCategory = lambda("Mark", 2);
I guess below code should get you the value you are trying to get.
var lead3 = SubCategoryDictionary["Mark"].SingleOrDefault(x => x.Key == 2).Value;
The idea is to use the Key of the first dictionary and get the value of it than filter it with SingleOrDefault method by providing a key to the inner dictionary value you are interested in.
Hope this helps

Adding a key value pair in a dictionary inside a dictionary

I have a dictionary < string,object > which has a mapping of a string and a dictionary < string,int >. How do I add a key value pair in the inside dictionary < string ,int > ?
Dictionary <string,object> dict = new Dictionary <string,object>();
Dictionary <string,int> insideDict = new Dictionary <string,int>();
// ad some values in insideDict
dict.Add("blah",insideDict);
So now the dict has a dictionary mapped with a string.Now I want to separately add values to the insideDict.
I tried
dict["blah"].Add();
Where am I going wrong?
Do you mean something like this?
var collection = new Dictionary<string, Dictionary<string, int>>();
collection.Add("some key", new Dictionary<string, int>());
collection["some key"].Add("inner key", 0);
Something like below
Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("1", new Dictionary<string, int>());
(OR) if you already have defined the inner dictionary then
Dictionary<string, object> dict = new Dictionary<string, object>();
Dictionary<string, int> innerdict = new Dictionary<string, int>();
dict.Add("1", innerdict); // added to outer dictionary
string key = "1";
((Dictionary<string, int>)dict[key]).Add("100", 100); // added to inner dictionary
Per your comment tried this but screwed up somewhere
You didn't got it cause of your below line where you forgot to cast the inner dictionary value to Dictionary<string, int> since your outer dictionary value is object. You should rather have your outer dictionary declared strongly typed.
dict.Add("blah",insideDict); //forgot casting here
Dictionary<string, Dictionary<string,TValue>> dic = new Dictionary<string, Dictionary<string,TValue>>();
Replace the TValue with your value type.

Get Values from dictionary present in List

I have a list like,
List<string> list = new List<string>();
list.Add("MEASUREMENT");
list.Add("TEST");
I have a dictionary like,
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("BPGA", "TEST");
dict.Add("PPPP", "TEST");
dict.Add("RM_1000", "MEASUREMENT");
dict.Add("RM_2000", "MEASUREMENT");
dict.Add("CDMA", "TEST");
dict.Add("X100", "XXX");
Now, I want to get all matched data from dictionary based on list.
Means, all data from list match with dict value then get new dictionary with following mathched values
Is there any way to achieve this by using lambda expression?
I want result like this.
Key Value
"BPGA", "TEST"
"PPPP", "TEST"
"RM_1000", "MEASUREMENT"
"RM_2000", "MEASUREMENT"
"CDMA", "TEST"
Thanks in advance!
You should be using the dictionary like it is intended to be used i.e. a common key with multiple values for example:
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>();
Then all you need to do when adding the values is:
dict.Add("TEST", new List<string>() { /*strings go in here*/ });
Then to get all the results from a key like:
List<string> testValues = dict["TEST"];
To make it safe however you should check that the key exists i.e.
if (dict.ContainsKey("TEST"))
{
//Get the values
}
Then to add values to a current key you go do something like:
dict["TEST"].Add("NewValue");
If you insist on keeping the same structure, although I do not recommend it, something like the following will work:
List<string> testKeys = new List<string>();
foreach (var pairs in dict)
{
if (pair.Value == "TEST")
{
testKeys.Add(pair.Key);
}
}
Or even the following LINQ statement:
List<string> testKeys = dict.Where(p => p.Value == "TEST").Select(p => p.Key).ToList();
For a generic query to find the ones from your list use:
List<string> values = dict.Where(p => list.Contains(p.Value)).ToList();

Categories

Resources