Why doesn't DbDataAdapter implement IDbDataAdapter?

  • Thread starter Thread starter Brian Takita
  • Start date Start date
B

Brian Takita

Hello,

It seems like all of the classes that inherit DbDataAdapter also
implement IDbDataAdapter.

The problem is making a class that uses a generic DataAdapter requires
both the DbDataAdapter and IDbDataAdapter.

This means the class has to ask for either a DbDataAdapter and unbox to
IDbDataAdapter or vice versa
or
The class has to ask for both a DbDataAdapter and the IDbDataAdapter.

Is there a possibility that IDbDataAdapter will be implemented in a
class that does not inherit DbDataAdapter?

If this is a bug, then the first solution will be better.
If this is by design, then the second solution is better.

Sincerely,
Brian Takita
www.briantakita.com
 
Hi Brian,

Brian Takita said:
Hello,

It seems like all of the classes that inherit DbDataAdapter also
implement IDbDataAdapter.

The problem is making a class that uses a generic DataAdapter requires
both the DbDataAdapter and IDbDataAdapter.

This means the class has to ask for either a DbDataAdapter and unbox to
IDbDataAdapter or vice versa
or
The class has to ask for both a DbDataAdapter and the IDbDataAdapter.

There is no (un)boxing here.
Is there a possibility that IDbDataAdapter will be implemented in a
class that does not inherit DbDataAdapter?

Certainly, DbDataAdapter is only an utility class.
 
Miha,
There is no (un)boxing here.

In this case there would be.
For example...

public void GenericDataAdapterFunction (DbDataAdapter dba) {
IDbDataAdapter idba = (IDbDataAdapter) dba;
idba.SelectCommand.CommandText = "select * from blah";
dba.Fill (this.SomeDataTable);
}
Certainly, DbDataAdapter is only an utility class.
All of the following classes inherit DbDataAdapter and implement
IDbDataAdapter.
System.Data.Odbc.OdbcDataAdapter
System.Data.OleDb.OleDbDataAdapter
System.Data.OracleClient.OracleDataAdapter
System.Data.SqlClient.SqlDataAdapter
System.Data.SqlServerCe.SqlCeDataAdapter
I couldn't find any classes that inherit from DbDataAdapter and do not
implement IDbDataAdapter.

Is there a way to represent a variable to be both a DbDataAdapter and
an IDbDataAdapeter without (un)boxing?
Does a .Net language support compile time checking to make sure an
object implements multiple interfaces and subclasses?

Sincerely,
Brian Takita
 
Hi Brian,

Brian Takita said:
Miha,


In this case there would be.
For example...

public void GenericDataAdapterFunction (DbDataAdapter dba) {
IDbDataAdapter idba = (IDbDataAdapter) dba;
idba.SelectCommand.CommandText = "select * from blah";
dba.Fill (this.SomeDataTable);
}

Actually no. There is no boxing or unboxing. What are you showing us is
called casting.
All of the following classes inherit DbDataAdapter and implement
IDbDataAdapter.
System.Data.Odbc.OdbcDataAdapter
System.Data.OleDb.OleDbDataAdapter
System.Data.OracleClient.OracleDataAdapter
System.Data.SqlClient.SqlDataAdapter
System.Data.SqlServerCe.SqlCeDataAdapter
I couldn't find any classes that inherit from DbDataAdapter and do not
implement IDbDataAdapter.

You can't foresee the future or what 3rd party providers look like.
Is there a way to represent a variable to be both a DbDataAdapter and
an IDbDataAdapeter without (un)boxing?
Does a .Net language support compile time checking to make sure an
object implements multiple interfaces and subclasses?

Nope. Why would you need it?
 
Miha,
Actually no. There is no boxing or unboxing. What are you showing us is
called casting.
True, its casting.
You can't foresee the future or what 3rd party providers look like.
Surely there has to be another reason that relates to how it is designed
now...
Nope. Why would you need it?
It would be allow the compiler to ensure that a variable fulfills two
parameters. Take a look at this snippit.

private void GenericDataAdapterFunction (DbDataAdapter dba) {
IDbDataAdapter idba = (IDbDataAdapter) dba;
idba.SelectCommand.CommandText = "select * from blah";
dba.Fill (this.SomeDataTable);
}

I want to take a DbDataAdapter (as in a Generic OleDbDataAdapter,
SqlDataAdapter, etc.) and use it to fill a DataTable.
You see that it accepts a DbDataAdapter argument named dba.
Unfortunately, DbDataAdapter does not have the SelectCommand, property.
However the IDbDataAdapter interface has the SelectCommand interface,
but its Fill method only accepts a DataSet as an argument.

I understand that the runtime will throw an exception if the cast does
not work, but I'd rather do a compile time check.

of course I can design it like
private void GenericDataAdapterFunction (DbDataAdapter dba,
IDbDataAdapter idba) {
....
}

public void SomeFunction () {
OleDbDataAdapter a = new OleDbDataAdapter ();
GenericDataAdapterFunction (a, a);
}

but doesn't strike you as a bit silly?

Brian Takita
 
but doesn't strike you as a bit silly?

Yes, but I believe there *is* a reason for it.

Basically, I think it's so you can get strong typing. Effectively,
we've got a situation like this:

using System;

public interface IFoo
{
string SomeProperty { get; }
}

public abstract class BaseClass
{
}

public class SpecialisedClass : BaseClass, IFoo
{
public int SomeProperty
{
get { return 5; }
}

string IFoo.SomeProperty
{
get { return "hello"; }
}

// Just so I don't have to specify /t:library
static void Main()
{
}
}

That means someone else can use

int x = new SpecialisedClass.SomeProperty;

Now if BaseClass implements IFoo, then it either has to provide a
(possibly abstract) public SomeProperty property of type string, in
which case SpecialisedClass can't expose its SomeProperty property of
type int, or it has to give a private explicit implementation, which it
basically can't do.

I know it's crazy, but I think it does just about make sense. I suspect
that if generics had been around, it wouldn't have been a problem, but
I'm not sure.
 
That means someone else can use

int x = new SpecialisedClass.SomeProperty;
That makes sense.

OleDbDataAdapter seems to implement its own SelectCommand as well as
IDbDataAdapter.SelectCommand.
public OleDbCommand SelectCommand {get;set;}
IDbCommand IDbDataAdapter.SelectCommand {get;set;}

Brian Takita
 
Back
Top