[英]Using StringBuilder and a DataTable, How do I return multiple rows in three columns without breaking when there is only one row?
I have a function that returns a list of email addresses from a SQL stored Proc based on an ID called. 我有一个函数,该函数根据调用的ID从SQL存储的Proc返回电子邮件地址列表。 It is using StringBuilder and returns one column.
它使用StringBuilder并返回一列。 For most IDs there are 4 or less email addresses and this format is fine.
对于大多数ID,电子邮件地址为4个或更少,这种格式很好。 However we are now getting more IDs with 10+ email addresses and this is making the page too long.
但是,我们现在获得了更多具有10多个电子邮件地址的ID,这使页面过长。
The function is: 该函数是:
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();
I have tried using the following but it breaks when there are too few addresses to return: 我尝试使用以下内容,但是在返回的地址太少时会中断:
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();
Using Linq's Take
function, you could replace the following block of code from your first example: 使用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>");
}
with this: 有了这个:
foreach (var row in dt.Rows.OfType<DataRow>().Take(3))
{
sb.Append("<tr><td>");
sb.Append(row["EMail"].ToString());
sb.Append("</td></tr>");
}
Since Take returns up to the specified number of elements from the beginning of the sequence, this block of code will be run anywhere from 0 to 3 times. 由于Take从序列的开头最多返回指定数量的元素,因此该代码块将在0到3次之间任意运行。 You'll have 3 addresses displayed at most (even if more are present), and you won't get an
IndexOutOfRangeException
if you have less than 3. 您最多将显示3个地址(即使存在更多地址),如果少于3个,则不会获得
IndexOutOfRangeException
。
UPDATE: ASP.NET 2.0 Compatible 更新:与ASP.NET 2.0兼容
Since you can't use Linq, this should have the same result: 由于您不能使用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>");
}
The expression dt.Rows.Count > 3 ? 3 : dt.Rows.Count
表达式
dt.Rows.Count > 3 ? 3 : dt.Rows.Count
dt.Rows.Count > 3 ? 3 : dt.Rows.Count
uses the ?
dt.Rows.Count > 3 ? 3 : dt.Rows.Count
使用?
operator to cause the for
loop to iterate over all of the email addresses unless there are more than 3, in which case it will iterate only 3 times. 运算符使
for
循环遍历所有电子邮件地址,除非有3个以上,否则将仅循环3次。
Instead of building a html table with a string builder have you considered using an asp.net repeater control . 您可以考虑使用asp.net转发器控件,而不是使用字符串生成器构建html表。 You can bind the DataTable directly to the repeater and then control the html from the html design surface.
您可以将DataTable直接绑定到转发器,然后从html设计图面控制html。 It would prove to be much more flexible for what you are trying to do.
对于您想做的事情,它将被证明更加灵活。 This is assuming you're using asp.net.
这是假设您正在使用asp.net。
Also see my post on creating a custom asp.net control as this will give you the most flexibility as well as encapsulate your custom html logic. 另请参阅我关于创建自定义asp.net控件的文章,因为这将为您提供最大的灵活性并封装您的自定义html逻辑。
Enjoy! 请享用!
I think Doug is on the right track, but if you insist on doing it with StringBuilder and a for-loop, try this: 我认为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.