Looping through the rows, updating the values as you go is definitely a solution, and a quite easy one:
foreach (DataRow row in table.Rows)
{
if (row.IsNull("foo")) row["foo"] = "-";
if (row.IsNull("bar")) row["bar"] = "-";
row["date"] = ((DateTime)row["date"]).Date;
}
Alternatively, you could create new columns in the table, using expressions to autogenerate content:
table.Columns.Add("foo_dash", typeof(string), "IsNull(foo, '-')");
table.Columns.Add("bar_dash", typeof(string), "IsNull(bar, '-')");
(I don't know the date functions in ADO.NET so you will have to figure the last one out yourself.)
You have tagged your post ASP.NET, so I guess it is reasonable to assume that you are going to bind your DataTable
to some multi-record data control (GridView
, Repeater
, etc). If this is the case, it might be better to do the transformations during databinding instead:
protected void theGrid_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
var data = e.DataItem as DataRowView;
if (data != null)
{
if (data.Row.IsNull("foo")) e.Row.Cells[0] = "-";
if (data.Row.IsNull("bar")) e.Row.Cells[0] = "-";
}
}
While this seems to require a bit more code, it also gives you more flexibility. Example:
if (data.Row.IsNull("importantField")) e.Row.CssClass = "error";
In a GridView
, the date can be formatted using a DataFormatString
in the column declaration:
<asp:BoundField DataField="data" DataFormatString="{0:d}" />
Similar when databinding a Repeater
:
<%# Eval("date", "{0:d}") %>