也许SO不是这个地方,如果不是,我道歉,但我不禁想到有更好的方法来做到这一点。这似乎是一种粗略而不是非常干净的方法,可以检查我所处的结果集,然后执行相应的操作。有人有什么建议吗? (请忽略我总是返回null的事实。)
public MemberDto Load(long entityId)
{
using (var cn = new SqlConnection(@"connectionstringstuff"))
{
cn.Open();
using (SqlCommand cm = cn.CreateCommand())
{
cm.CommandText = "Client.[MemberGet]";
cm.CommandType = CommandType.StoredProcedure;
cm.Parameters.AddWithValue("@EntityId", entityId);
using (IDataReader dr = cm.ExecuteReader())
{
var memberModel = new MemberDto();
do
{
while (dr.Read())
{
var sdr = new SafeDataReader(dr);
var firstColumn = sdr.GetName(0);
if (firstColumn.StartsWith("Attribute"))
{
AddAttribute(memberModel, sdr);
}
else if (firstColumn.StartsWith("AlternateId"))
{
AddAlternateId(memberModel, sdr);
}
else
{
memberModel.ClientId = sdr.GetInt64("ClientId");
memberModel.Id = sdr.GetInt64("EntityId");
memberModel.Name = sdr.GetString("EntityName");
}
}
} while (dr.NextResult());
}
}
}
return null;
}
private void AddAttribute(MemberDto model, SafeDataReader reader)
{
model.Attributes.Add(
reader.GetInt32("AttributeTypeId").As<EntityAttributeType>(),
reader.GetString("Value"));
}
private void AddAlternateId(MemberDto model, SafeDataReader reader)
{
model.Attributes.Add(
reader.GetInt32("AlternateIdTypeId").As<EntityAttributeType>(),
reader.GetString("Value"));
}
答案 0 :(得分:0)
我们处理这个问题的方法不是循环使用nextresult,而是显式编码以匹配底层数据。这种方法的预期结果在某种程度上更加明显(当然,我认为)。
这是一个重写示例,假设顺序是成员模型,属性和替代。
while (dr.Read())
{
var sdr = new SafeDataReader(dr);
memberModel.ClientId = sdr.GetInt64("ClientId");
memberModel.Id = sdr.GetInt64("EntityId");
memberModel.Name = sdr.GetString("EntityName");
}
if (dr.NextResult())
{
while (dr.Read())
{
AddAttribute(memberModel, new SafeDataReader(dr));
}
}
if (dr.NextResult())
{
while (dr.Read())
{
AddAlternateId(memberModel, new SafeDataReader(dr));
}
}
答案 1 :(得分:0)
也许所有返回多个结果集的sp应始终首先包含一个结果集,指定以哪种顺序返回哪些结果集:
dr = multRsCmd.ExecureReader();
// first rs is always the meta
List<string> resultSetIds = new List<string>();
while (dr.Read())
resultSetIds.Add(dr[0]
foreach (string rsId in resultSetIds)
{
if (!dr.NextResult())
break; // or throw, should not happen
if (rsId == "ClientDataWithAttribute")
{
// code to handle the exact rs layout for ClientDataWithAttribute
//
//
}
else if (rsId == "ClientDataWithAltId")
{
// code to handle the exact rs layout for ClientDataWithAltId
//
//
}
else if (rsId == "ClientData")
{
// code to handle the exact rs layout for ClientData
//
//
}
}
这当然是为重构而尖叫:
dr = multRsCmd.ExecureReader();
// first rs is always the meta
List<string> resultSetIds = new List<string>();
while (dr.Read())
resultSetIds.Add(dr[0]
foreach (string rsId in resultSetIds)
{
if (!dr.NextResult())
break; // or throw, should not happen
// pull subclass out of registry of readers
ResultSetReader rsr = ResultSetReaders.Find(rsId);
// subclass cleanly holds the layout-dependent logic
memberModel = rsr.FromDataReader(dr);
}
看起来很干净,但你甚至可以在ResultSetReader中添加默认行为来驱动配置文件或其他来源的DTO属性映射,并且只有在你获得特殊条件时才会覆盖。你明白了。