开发者

Modify values on-the-fly during SqlAdapter.Fill( )

What would the proper way be to modify values on the fly as they are loaded into a DataTable by SqlAdapter.Fill()?

I have globalized my application's log messages. An integer indicating the event type and serialized data relevant to the event is stored in the database as show below. When I display the logged events through a DataGridView control to the user, I interpolate the data to a formatting string.

event_type event_timestamp     event_details
============================================
3          2010-05-04 20:49:58 jsmith
1          2010-05-04 20:50:42 jsmith
...

I am currently iterating through the DataTable's rows to format the messages.

public class LogDataTable : DataTable
{
    public LogDataTable()
    {
        Locale = CultureInfo.CurrentCulture;
        Columns.AddRange(new DataColumn[] {
            new DataColumn("event_type", typeof(Int32)),
            new DataColumn("event_timestamp", typeof(DateTime)),
            new DataColumn("event_details", typeof(String))});
    }
}

...
using (SqlDataAdapter adapter = new SqlDataAdapter(...)) 
{
    adapter.SelectCommand.Parameters.AddRange(new Object[] {
       ...
    });
    adapter.Fill(table);
}
开发者_如何学JAVAforeach (DataRow row in table.Rows)
{
    switch ((LogEventType)row["event_type"])
    {
       case LogEventType.Create:
           row["event_details"] = String.Format(Resources.Strings.LogEventCreateMsg, row["event_details"];
           break;
       case LogEventType.Create:
           row["event_details"] = String.Format(Resources.Strings.LogEventCreateMsg, row["event_details"];
           break;
       ...

The end result as displayed would resemble:

Type   Date and Time       Details
====================================================================
[icon] 2010-05-04 20:49:58 Failed login attempt with username jsmith
[icon] 2010-05-04 20:50:42 Successful login with username jsmith
...

It seems wasteful to iterate the result set twice-- once as the table is filled by the adapter, and again to perform the replacements. I would really like to do the replacement on-the-fly in my LogDataTable class as it is being populated.

I have tried overriding an OnRowChanging method in LogDataTable, which throws an InRowChangingEventException.

protected override void OnRowChanging(DataRowChangeEventArgs e)
{
    base.OnRowChanging(e);
    switch ((LogEventType)row["event_type"])
    ...

I have tried overriding an OnRowChanged method, which throws a StackOverflowException (I assume changing it re-triggers the method ad infinitum?).

I have tried overriding an OnTableNewRow method, which does not throw an exception but appears not to be invoked (I assume only when a user adds a row in the view, which I've prevented).

I'd greatly appreciate any assistance anyone can give me.


IMO, what you're currently doing is fine. You can very well change your in-memory DataTable items once it is filled rather than changing them on the fly as it may degrade your performance since it interrupts the IO operation.

On the other hand, if you're the DB Admin you can better ETL your first column :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜