Я пытаюсь найти хороший способ получить все мои запросы, которые заполняют раскрывающиеся списки, за одну поездку в БД и использовать дженерики, поэтому мне не нужно создавать кучу пользовательских классов. Я хотел бы избежать создания множества пользовательских классов, таких как Class IntStringPair
, Class StringStringPair
, Class StringIntPair
и т. д.
Я знаю, что в C# есть KeyValuePair, поэтому я попытался использовать его, но выдает исключение: 'System.Collections.Generic.KeyValuePair[System.Int32,System.String]' must declare a default (parameterless) constructor in order to be constructed during mapping.'
Я видел этот пост: KeyValuePair - нет конструктора без параметров?
но что странно, это работает, если я попадаю только в одну таблицу, но не работает, если я использую IMultipleResults
из хранимой процедуры.
Итак, это работает:
using (MyDataContext db = new MyDataContext(Config.CoreDBConnectionString))
{
return db.MyTable.Select(p => new KeyValuePair<string, string>(p.Field1, p.Field2)).ToList();
}
Но это не удается:
using (MyDataContext db = new MyDataContext(Config.CoreDBConnectionString))
{
System.Data.Linq.IMultipleResults r = db.GetLookups();
return r.GetResult<KeyValuePair<int,string>>().ToList();
}
Если бы я мог заставить этот последний работать, у меня было бы лучшее из обоих миров, одна поездка в БД и универсальное решение.
Я тоже пробовал Dictionary
, но всегда сталкиваюсь с проблемами сериализации. Приложение, над которым я работаю, устарело, поэтому вместо Entity Framework оно использует Linq to SQL.
Итак, есть ли способ сделать это, не создавая кучу классов, желательно что-то встроенное в C#/.NET, которое использует дженерики и позволяет мне получить несколько наборов результатов за одну поездку?
Если вы создадите свой собственный общий парный класс, вы можете использовать его. Я создал один со свойствами Value1
и Value2
, но вместо этого вы можете создать Key
/Value
, если хотите:
public class DBPair<T1, T2> {
T1 v1;
T2 v2;
public DBPair() {
}
public DBPair(T1 v1, T2 v2) {
this.v1 = v1;
this.v2 = v2;
}
public T1 Value1
{
get; set;
}
public T2 Value2
{
get; set;
}
}
ПРИМЕЧАНИЕ. Если вам нужны некоторые другие возможности KeyValuePair
, такие как проверка равенства элементов или генерация хэш-кода, вам нужно будет добавить эти методы или перенести результаты в новый KeyValuePair
после извлечения.
Затем вы можете использовать его так:
using (MyDataContext db = new MyDataContext(Config.CoreDBConnectionString))
return db.GetLookups().GetResult<DBPair<int,string>>().ToList();
Ваш первый пример вызывает стандартный конструктор, который принимает два параметра. Ваш второй пример вызывает
GetResult
, который создает объект без параметров, а затем устанавливает значения, которые он не может сделать дляKeyValuePair
(как указано в вашей ссылке,KeyValuePair
является структурой и не имеет конструктора без параметров, доступного через отражение. Вам нужно просто определить ваш собственный альтернативный универсальный класс KVP.