#c# #linq #dictionary
Вопрос:
Кажется, мне трудно найти простой способ вставить мою старую и новую регистрацию в словарь, отформатированный как
Dictionary<int, List<Registration>, List<Registration>>
Где первый список содержит старую регистрацию, а другой содержит новую регистрацию.
У них есть идентификатор в commmon, который должен быть ключом, и если это не так, то другой список должен быть пустым.
Кажется, мне трудно найти оператор Linq, способный сделать это, я бы предположил, что это была работа для GroupBy или GroupJoin, но не могу понять, как это должно выглядеть..
MVC: https://dotnetfiddle.net/BIbPqY
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
Dictionary<string, object> openWith =
new Dictionary<string, object>();
openWith.Add("txt", "notepad.exe");
openWith.Add("bmp", "paint.exe");
openWith.Add("dib", "paint.exe");
openWith.Add("rtf", "wordpad.exe");
Registration reg1 = new Registration()
{
id = 1,
attributes = openWith
};
Registration reg2 = new Registration()
{
id = 2,
attributes = openWith
};
Registration reg3 = new Registration()
{
id = 1,
attributes = openWith
};
Registration reg4 = new Registration()
{
id = 2,
attributes = openWith
};
List<Registration> oldReg = new List<Registration>() {reg1, reg2 };
List<Registration> newReg = new List<Registration>() {reg3, reg4 };
Console.WriteLine("Hellow World");
}
public class Registration
{
public int id {get; set;}
public Dictionary<string, object> attributes {get; set;}
}
}
Мой текущий способ обработки — создать два словаря с помощью groupBy
Dictionary<int, List<Registration>> oldRegDic =
oldReg.GroupBy(o => o.id).ToDictionary(g => g.Key, g => g.ToList());
Dictionary<int, List<Registration>> newRegDic =
newReg.GroupBy(o => o.id).ToDictionary(g => g.Key, g => g.ToList());
Dictionary<int, (List<Registration>, List<Registration>)> oldAndNewRegistrationDictionary = new();
foreach (KeyValuePair<int, List<Registration>> newReg in newRegistrationDictionary)
{
(List<EntityRegistration>, List<EntityRegistration>) oldNewPair = new()
{
Item1 = oldRegDic[newReg.Key], Item2 = newRegDic[newReg.Key]
};
}
А затем перебрать их оба и добавить их в новый словарь, но это выглядит очень неэффективно.
Комментарии:
1.
Dictionary<int, List<Registration>, List<Registration>>
не имеет смысла.Dictionary<TKey, TValue>
принимает только два параметра общего типа. Может быть, вы намеревались создать класс, в котором есть оба списка?class Foo { public List<Registration> list1, list2; }
а потом естьDictionary <int, Foo>
?2. это было сделано для того, чтобы избежать создания для него целого класса, но я понимаю вашу точку зрения
Ответ №1:
Здесь хорошо иметь полное соединение, но его можно эмулировать двумя запросами:
var query1 =
from n in newReg
join o in oldReg on n.id equals o.id into gj
from o in gj.DefaultIfEmpty()
select new { id = n.id, n, o };
var query2 =
from o in oldReg
join n in newReg on o.id equals n.id into gj
from n in gj.DefaultIfEmpty()
where n == null
select new { id = o.id, n, o };
var result = query1.Concat(query2)
.ToDictionary(x => x.id, x => Tuple.Create(x.o, x.n));