PC Review Forums Newsgroups Microsoft DotNet Microsoft ADO .NET An easy way to find whether a SqlDataReader contains a field

Reply

An easy way to find whether a SqlDataReader contains a field

 
Thread Tools Rate Thread
Old 05-07-2003, 04:32 PM   #1
Andrei Badea
Guest
 
Posts: n/a
Default An easy way to find whether a SqlDataReader contains a field


Hi all,

it seems there's no easy way to find out whether a SqlDataReader contains a
field (given the field name). It has the GetOrdinal() method, but it throws
an exception if the readed doesn't contain the field. I could probably use
the GetSchemaTable method, but it seems it's a little too complicated for
what I want to do. Deep in the System.Data namespace there's a class names
FieldNameLookup which is used by SqlDataReader.GetOrdinal() to lookup the
field names, and it also contains an IndexOfName() method, which returns -1
if the field name is unknown. I can't understand why SqlDataReader doesn't
also expose a method like this (since it's easy and possible to do it). Or
am I missing something?

Regards,

Andrei



  Reply With Quote
Old 05-07-2003, 06:58 PM   #2
Pete Wright
Guest
 
Posts: n/a
Default Re: An easy way to find whether a SqlDataReader contains a field

I found the class you speak of, looking in WinCV, but it's not in the MSDN
documentation that comes with VS.NET 2003. To my mind that would put
FieldNameLookup out of bounds as an internal, unsupported and very much
subject to change class. So, that leaves you with, as you said,
GetSchemaTable, or GetOrdinal. GetSchemaTable would be the best bet, since
your code intends to examine the schema of a set of results, it makes sense
to use a class that is designed to let you do just that.

Using GetSchemaTable to do what satisfy your particular problem is actually
trivial. It's worth explaining how GetSchemaTable works though.
GetSchemaTable returns a table holding the schema of the reader. There is
one row in the table for each column returned in your reader, and the
columns of the schema table define properties of the reader's result set,
such as the column name, size, data type and so on.

Now, since GetSchemaTable returns a table, all we really need to do is ask
ADO.NET to filter the rows in that table to just the row matching the column
we want (remember, the schema table holds 1 row per column). The easiest way
to do this is with the default view.

For example, if I were looking for a row called "FOO" in a reader's results,
I could do this
DataView myView = myReader.GetSchemaTable().DefaultView;

myView.RowFilter = "ColumnName = 'Foo' ";

All i now need to do is check myView.Count to see if it is zero or not. If
myView.Count is zero, then the column in question is not in the result set.
If on the other hand I get anything other than zero (probably a 1), then the
column I'm looking for exists.


Of course, dumping all that code into your app everytime you want to check
the existence of a column is not a particularly elegant idea. It would be
better to go and invent a function to do the work for you easily. I've
written one for you and included it below. Using this function, you can
just write
if ( columnExists(myReader, "ColumnName") ) { } else { }

So, here's the function
private bool columnExists( SqlDataReader reader, string columnName )

{

reader.GetSchemaTable().DefaultView.RowFilter = "ColumnName= '" +

columnName + "'";

return (reader.GetSchemaTable().DefaultView.Count > 0);

}

Hope that helps,
--
Peter Wright
Author of ADO.NET Novice To Pro, from Apress Inc.


"Andrei Badea" <andrei.badea@centrum.cz> wrote in message
news:%236teVJwQDHA.2128@TK2MSFTNGP12.phx.gbl...
> Hi all,
>
> it seems there's no easy way to find out whether a SqlDataReader contains

a
> field (given the field name). It has the GetOrdinal() method, but it

throws
> an exception if the readed doesn't contain the field. I could probably use
> the GetSchemaTable method, but it seems it's a little too complicated for
> what I want to do. Deep in the System.Data namespace there's a class names
> FieldNameLookup which is used by SqlDataReader.GetOrdinal() to lookup the
> field names, and it also contains an IndexOfName() method, which

returns -1
> if the field name is unknown. I can't understand why SqlDataReader doesn't
> also expose a method like this (since it's easy and possible to do it). Or
> am I missing something?
>
> Regards,
>
> Andrei
>
>
>



  Reply With Quote
Old 05-07-2003, 07:22 PM   #3
Andrei Badea
Guest
 
Posts: n/a
Default Re: An easy way to find whether a SqlDataReader contains a field

Pete,

thanks for your (pretty extensive) answer. I agree I can't use
FieldNameLookup, I was just trying to point out that SqlDataReader could
very easily export its IndexOf() method. But of course GetSchemaTable() has
a better design. However, I'm not sure it will work in my case. I am trying
to write a class to encapsulate data. This class has several fields and
should be able to read itself from a data reader (by passing an IDataRecord
interface).

class Person
{
public static void FromDataRecord(IDataRecord dataRecord)
{
....
}
}

The problem is the IDataRecord could contain just some of the needed fields,
not all of them. So the Person class has to find out which fields are in the
IDataRecord. Because the data reader could contain lots (e.g. 100) of
persons, the FromDataRecord() method will be called 100 times. And looking
up the existent fields in the DataTable returned by GetSchemaTable() during
each call will probably by pretty slow. I guess I will have to find another
way to do this.

Regards,

Andrei

"Pete Wright" <pete@codemonkey.demon.co.uk> wrote in message
news:be705d$858$1$8300dec7@news.demon.co.uk...
> I found the class you speak of, looking in WinCV, but it's not in the MSDN
> documentation that comes with VS.NET 2003. To my mind that would put
> FieldNameLookup out of bounds as an internal, unsupported and very much
> subject to change class. So, that leaves you with, as you said,
> GetSchemaTable, or GetOrdinal. GetSchemaTable would be the best bet, since
> your code intends to examine the schema of a set of results, it makes

sense
> to use a class that is designed to let you do just that.
>
> Using GetSchemaTable to do what satisfy your particular problem is

actually
> trivial. It's worth explaining how GetSchemaTable works though.
> GetSchemaTable returns a table holding the schema of the reader. There is
> one row in the table for each column returned in your reader, and the
> columns of the schema table define properties of the reader's result set,
> such as the column name, size, data type and so on.
>
> Now, since GetSchemaTable returns a table, all we really need to do is ask
> ADO.NET to filter the rows in that table to just the row matching the

column
> we want (remember, the schema table holds 1 row per column). The easiest

way
> to do this is with the default view.
>
> For example, if I were looking for a row called "FOO" in a reader's

results,
> I could do this
> DataView myView = myReader.GetSchemaTable().DefaultView;
>
> myView.RowFilter = "ColumnName = 'Foo' ";
>
> All i now need to do is check myView.Count to see if it is zero or not. If
> myView.Count is zero, then the column in question is not in the result

set.
> If on the other hand I get anything other than zero (probably a 1), then

the
> column I'm looking for exists.
>
>
> Of course, dumping all that code into your app everytime you want to check
> the existence of a column is not a particularly elegant idea. It would be
> better to go and invent a function to do the work for you easily. I've
> written one for you and included it below. Using this function, you can
> just write
> if ( columnExists(myReader, "ColumnName") ) { } else { }
>
> So, here's the function
> private bool columnExists( SqlDataReader reader, string columnName )
>
> {
>
> reader.GetSchemaTable().DefaultView.RowFilter = "ColumnName= '" +
>
> columnName + "'";
>
> return (reader.GetSchemaTable().DefaultView.Count > 0);
>
> }
>
> Hope that helps,
> --
> Peter Wright
> Author of ADO.NET Novice To Pro, from Apress Inc.
>
>
> "Andrei Badea" <andrei.badea@centrum.cz> wrote in message
> news:%236teVJwQDHA.2128@TK2MSFTNGP12.phx.gbl...
> > Hi all,
> >
> > it seems there's no easy way to find out whether a SqlDataReader

contains
> a
> > field (given the field name). It has the GetOrdinal() method, but it

> throws
> > an exception if the readed doesn't contain the field. I could probably

use
> > the GetSchemaTable method, but it seems it's a little too complicated

for
> > what I want to do. Deep in the System.Data namespace there's a class

names
> > FieldNameLookup which is used by SqlDataReader.GetOrdinal() to lookup

the
> > field names, and it also contains an IndexOfName() method, which

> returns -1
> > if the field name is unknown. I can't understand why SqlDataReader

doesn't
> > also expose a method like this (since it's easy and possible to do it).

Or
> > am I missing something?
> >
> > Regards,
> >
> > Andrei
> >
> >
> >

>
>



  Reply With Quote
Reply



Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off