从SQL Reader到Object的复杂映射

时间:2015-01-17 19:37:46

标签: c#

我需要将存储过程的结果映射到复杂对象:

假设我的存储过程返回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对象中。

2 个答案:

答案 0 :(得分:1)

根据您对评论的回答,听起来似乎唯一元组(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()
});

如果您确实需要使用上述类的结构,请定制以适应。

答案 1 :(得分:0)

您可以使用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();
}