Мне нужно сопоставить результат хранимой процедуры с сложным объектом:
Допустим, моя хранимая процедура возвращает столбцы A, B, C, D, E, F
У меня есть класс, скажем:
class ABC{
public int A;
public string B;
public int C;
public virtual ICollection<DEF> DEFObj;
}
и класс DEF:
class DEF{
int value;
string comment;
}
Итак, здесь мне нужно взять значения столбца D, E, F и сохранить их в ICollection<DEF>
в виде списка.
Какой был бы лучший способ сделать это, мог бы Automapper быть хорошим местом для начала или есть что-то еще?
PS: Мои данные находятся в объекте SQL Reader.
Основываясь на ваших ответах на комментарии, кажется, что между уникальным кортежем (A, B, C)
и, возможно, многими потенциально не уникальными значениями (D, E, F)
взаимосвязь "один ко многим". Это поддается интерфейсу IDictionary<ABC, ICollection<DEF>>
.
Когда вы используете SqlDataReader
, вам все равно придется заплатить цену за итерацию, так что вы можете также получить свои объекты за один раз.
IDictionary<ABC, ICollection<DEF>> data = new Dictionary<ABC, ICollection<DEF>>();
int _a = reader.GetOrdinal("a"), _b = reader.GetOrdinal("b"), _c = reader.GetOrdinal("c");
int _value = reader.GetOrdinal("value"), _comment = reader.GetOrdinal("comment");
while (reader.Read()) {
ABC key = new ABC { A = reader.GetInt32(_a), B = reader.GetString(_b), C = reader.GetInt32(_c) };
ICollection<DEF> values;
if (!data.TryGetValue(key, out values)) {
data[key] = (values = new List<DEF>());
}
values.Add(new DEF { value = reader.GetInt32(_value), comment = reader.GetString(_comment) });
}
Теперь вы можете сохранить свои отношения отдельно от своей модели, но если вы хотите денормализовать их в модели представления, например, вы можете использовать:
class ABCDEF {
public int A { get; set; }
public string B { get; set; }
public int C { get; set; }
public ICollection<DEF> DEF { get; set; }
}
И заселяйте, но вы предпочитаете. Пример использования LINQ:
data.Select(d => new ABCDEF {
A = d.Key.A,
B = d.Key.B,
C = d.Key.C,
DEF = d.Value.ToArray()
});
Если вам нужно использовать структуру вышеперечисленных классов, подойдите к ней.
Вы можете использовать linq для создания объектов довольно чистым способом.
using (SqlDataReader reader = CallStoredProcedure())
{
return reader.Cast<System.Data.Common.DbDataRecord>().Select(rec => new ABC()
{
A = (int)rec[0],
B = rec.GetString(1),
C = (int)rec[2],
DEFObj = // iterate over rec[3]? Don't know what your data looks like at this point...
}).toList();
}