繁体   English   中英

使用StringBuilder和DataTable,当只有一行时,如何在不中断的情况下返回三列中的多行?

[英]Using StringBuilder and a DataTable, How do I return multiple rows in three columns without breaking when there is only one row?

我有一个函数,该函数根据调用的ID从SQL存储的Proc返回电子邮件地址列表。 它使用StringBuilder并返回一列。 对于大多数ID,电子邮件地址为4个或更少,这种格式很好。 但是,我们现在获得了更多具有10多个电子邮件地址的ID,这使页面过长。

该函数是:

DataTable dt = DAL.ExecStoredProc(DAL.DatabaseName.DB, "storedProc", param);
StringBuilder sb = new StringBuilder();
sb.Append("<br/><br/>");
sb.Append("<table border='0' cellpadding='3'>");
for (int i = 0; i < dt.Rows.Count; i++)
{
    sb.Append("<tr><td>");
    sb.Append(dt.Rows[i]["EMail"].ToString());
    sb.Append("</td></tr>");
}
sb.Append("</table>");
return sb.ToString();

我尝试使用以下内容,但是在返回的地址太少时会中断:

DataTable dt = DAL.ExecStoredProc(DAL.DatabaseName.DB, "storedProc", param);
StringBuilder sb = new StringBuilder();
sb.Append("<br/><br/>");
sb.Append("<table border='0' cellpadding='3'>");
for (int i = 0; i < dt.Rows.Count; i++)
{
    sb.Append("<tr><td>");
    sb.Append(dt.Rows[i]["EMail"].ToString());
    i++;
    sb.Append("</td>");
    sb.Append("<td>");
    sb.Append(dt.Rows[i]["EMail"].ToString());
    i++;
    sb.Append("</td>");
    sb.Append("<td>");
    sb.Append(dt.Rows[i]["EMail"].ToString());
    i++;
    sb.Append("</td></tr>");
}
sb.Append("</table>");
return sb.ToString();

使用Linq的Take函数,您可以从第一个示例中替换以下代码块:

for (int i = 0; i < dt.Rows.Count; i++)
{
    sb.Append("<tr><td>");
    sb.Append(dt.Rows[i]["EMail"].ToString());
    sb.Append("</td></tr>");
}

有了这个:

foreach (var row in dt.Rows.OfType<DataRow>().Take(3))
{
    sb.Append("<tr><td>");
    sb.Append(row["EMail"].ToString());
    sb.Append("</td></tr>");
}

由于Take从序列的开头最多返回指定数量的元素,因此该代码块将在0到3次之间任意运行。 您最多将显示3个地址(即使存在更多地址),如果少于3个,则不会获得IndexOutOfRangeException


更新:与ASP.NET 2.0兼容

由于您不能使用Linq,因此结果应相同:

for (int i = 0; i < (dt.Rows.Count > 3 ? 3 : dt.Rows.Count); i++)
{
    sb.Append("<tr><td>");
    sb.Append(dt.Rows[i]["EMail"].ToString());
    sb.Append("</td></tr>");
}

表达式dt.Rows.Count > 3 ? 3 : dt.Rows.Count dt.Rows.Count > 3 ? 3 : dt.Rows.Count使用? 运算符使for循环遍历所有电子邮件地址,除非有3个以上,否则将仅循环3次。

您可以考虑使用asp.net转发器控件,而不是使用字符串生成器构建html表。 您可以将DataTable直接绑定到转发器,然后从html设计图面控制html。 对于您想做的事情,它将被证明更加灵活。 这是假设您正在使用asp.net。

另请参阅我关于创建自定义asp.net控件的文章,因为这将为您提供最大的灵活性并封装您的自定义html逻辑。

请享用!

我认为Doug走在正确的轨道上,但是如果您坚持使用StringBuilder和for循环来做到这一点,请尝试以下操作:

DataTable dt = DAL.ExecStoredProc(DAL.DatabaseName.DB, "storedProc", param);

StringBuilder sb = new StringBuilder();
sb.Append("<br/><br/>");
sb.Append("<table border='0' cellpadding='3'>");

string rowFormat = "<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>";

for (int i = 0; i < dt.Rows.Count; i+=3)
{
    string[] rowEmails = { String.Empty, String.Empty, String.Empty };

    for (int j = 0; j < 3; j++)
    {
        if (i+j < dt.Rows.Count) rowEmails[j] = dt.Rows[i+j]["Email"].ToString();
    }

    sb.AppendFormat(rowFormat, rowEmails[0], rowEmails[1], rowEmails[2]);
}

sb.Append("</table>");

return sb.ToString();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM