У меня к этим двум словарям:
Dictionary<string, List<string>> dictionary_1 = new Dictionary<string, List<string>> { };
Dictionary<string, List<string>> dictionary_2 = new Dictionary<string, List<string>> { };
ключ и значения в обоих словарях (таблицы и столбцы):
DataTable old_database_columns = new DataTable();
DataTable new_database_columns = new DataTable();
list_of_table_of_old_database = db.Select("", "", "", "", "", "", "", "", "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.tables WHERE TABLE_SCHEMA = '" + old_database.Text.Trim() + "' ", "");
list_of_table_of_current_database = db.Select("", "", "", "", "", "", "", "", "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.tables WHERE TABLE_SCHEMA = '" + new_database.Text.Trim() + "' ", "");
List<string> table_list_old_database = new List<string> { };
List<string> table_list_new_database = new List<string> { };
for (i = 0; i < list_of_table_of_old_database.Rows.Count; i++) {
table_list_old_database.Add(list_of_table_of_old_database.Rows[i][0].ToString());
}
for (i = 0; i < list_of_table_of_current_database.Rows.Count; i++) {
table_list_old_database.Add(list_of_table_of_old_database.Rows[i][0].ToString());
}
for (j = 0; j < table_list_old_database.Count; j++)
{
old_database_columns = db.Select("", "", "", "", "", "", "", "", "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.columns WHERE TABLE_SCHEMA = '" + old_database.Text.Trim() + "' and TABLE_NAME = '" + table_list_old_database[j].ToString() + "' ", "");
for (i = 0; i < old_database_columns.Rows.Count; i++)
{
old_database_columns_list.Add(old_database_columns.Rows[i][0].ToString());
}
dictionary_1.Add(table_list_old_database[j], new List<string>(old_database_columns_list));
old_database_columns_list.Clear();
}
for (j = 0; j < table_list_new_database.Count; j++)
{
new_database_columns = db.Select("", "", "", "", "", "", "", "", "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.columns WHERE TABLE_SCHEMA = '" + new_database.Text.Trim() + "' and TABLE_NAME = '" + table_list_new_database[j].ToString() + "' ", "");
for (i = 0; i < new_database_columns.Rows.Count; i++)
{
new_database_columns_list.Add(new_database_columns.Rows[i][0].ToString());
}
dictionary_2.Add(table_list_new_database[j] , new List<string>(new_database_columns_list));
new_database_columns_list.Clear();
}
Итак, теперь мне нужно проверить, являются ли ключи (таблицы) одинаковыми, что таблицы доступны в обоих словарях, тогда
Мне нужно показать значение (столбцы) этого ключа (таблицы), который существует в словаре один, но не существует в словаре 2
Я не буду заверять эту работу, я ее не тестировал, и я также предполагаю, что это лучший способ сделать это, что я не знаю, или я не думал, но если бы мне пришлось это сделать, я бы сделал это это так:
Dictionary<string, List<string>> dictionary_1 = new Dictionary<string, List<string>> { };
Dictionary<string, List<string>> dictionary_2 = new Dictionary<string, List<string>> { };
// Fill those dictionaries...
// Check for non existing things in dictionary 2 but existing in 1
foreach (KeyValuePair<String, List<String>> _element in dictionary_1)
{
List<String> _valuesFrom2;
// Check if table exist
if (dictionary_2.TryGetValue(_element.Key, out _valuesFrom2))
{
//Check if column exist
foreach (String _value in _element.Value)
{
if (!_valuesFrom2.Contains(_value))
{
Console.WriteLine($"Dictionary 2, table {_element.Key} does not contain {_value}");
}
}
}
else
{
Console.WriteLine($"Dictionnary 2 does not contain : {_element.Key}");
}
}
У меня есть FullOuterJoin
расширения FullOuterJoin
linq, который я поддерживаю для такого рода операций. Тогда становится возможным
var lookup =
dictionary_1.Keys
.FullOuterJoin(
dictionary_2.Keys,
key1 => key1,
key2 => key2,
(key1, key2) => new { key1, key2 })
.ToLookup(x =>
x.key1 != null && x.key2 != null
? "both"
: x.key1 != null
? "dic1"
: "dic2",
x => x.key1 ?? x.key2);
var keysExclusivelyInDic1 = lookup["dic1"];
var keysExclusivelyInDic2 = lookup["dic2"];
var keysThatMatch = lookup["both"];
Реализация метода расширения FullOuterJoin
:
public static class JoinExtensions
{
public static IEnumerable<TResult> FullOuterGroupJoin<TLeft, TRight, TKey, TResult>(
this IEnumerable<TLeft> leftSeq,
IEnumerable<TRight> rightSeq,
Func<TLeft, TKey> keySelectorLeft,
Func<TRight, TKey> keySelectorRight,
Func<IEnumerable<TLeft>, IEnumerable<TRight>, TKey, TResult> projectionSelector,
IEqualityComparer<TKey> comparer = null)
{
comparer = comparer ?? EqualityComparer<TKey>.Default;
var leftLookup = leftSeq.ToLookup(keySelectorLeft, comparer);
var rightLookup = rightSeq.ToLookup(keySelectorRight, comparer);
var keys = new HashSet<TKey>(leftLookup.Select(g => g.Key), comparer);
keys.UnionWith(rightLookup.Select(g => g.Key));
var join = keys
.Select(key => projectionSelector(leftLookup[key], rightLookup[key], key));
return join;
}
public static IEnumerable<TResult> FullOuterJoin<TLeft, TRight, TKey, TResult>(
this IEnumerable<TLeft> leftSeq,
IEnumerable<TRight> rightSeq,
Func<TLeft, TKey> keySelectorLeft,
Func<TRight, TKey> keySelectorRight,
Func<TLeft, TRight, TKey, TResult> projectionSelector,
TLeft defaultLeft = default(TLeft),
TRight defaultRight = default(TRight),
IEqualityComparer<TKey> comparer = null)
{
comparer = comparer ?? EqualityComparer<TKey>.Default;
var leftLookup = leftSeq.ToLookup(keySelectorLeft, comparer);
var rightLookup = rightSeq.ToLookup(keySelectorRight, comparer);
var keys = new HashSet<TKey>(leftLookup.Select(g => g.Key), comparer);
keys.UnionWith(rightLookup.Select(g => g.Key));
var join = keys
.SelectMany(
key => leftLookup[key].DefaultIfEmpty(defaultLeft),
(key, leftItem) => new { key, leftItem })
.SelectMany(
leftItemAndKey =>
rightLookup[leftItemAndKey.key]
.DefaultIfEmpty(defaultRight),
(leftItemAndKey, rightItem) =>
projectionSelector(
leftItemAndKey.leftItem,
rightItem,
leftItemAndKey.key));
return join;
}
public static IEnumerable<TResult> FullOuterJoin<TLeft, TRight, TKey, TResult>(
this IEnumerable<TLeft> leftSeq,
IEnumerable<TRight> rightSeq,
Func<TLeft, TKey> keySelectorLeft,
Func<TRight, TKey> keySelectorRight,
Func<TLeft, TRight, TResult> projectionSelector,
TLeft defaultLeft = default(TLeft),
TRight defaultRight = default(TRight),
IEqualityComparer<TKey> comparer = null)
{
return leftSeq
.FullOuterJoin(
rightSeq,
keySelectorLeft,
keySelectorRight,
(leftItem, rightItem, _) => projectionSelector(leftItem, rightItem),
defaultLeft,
defaultRight,
comparer);
}
}