Inherit from DataSet

M

Mike

I need to expand the DataSet class by inheriting from it and adding
functions that work on the data in the tables. However, since I can't
upcast how can I get my base DataSet object assigned an actual
DataSet?

e.g.

public class MyDataSet : DataSet
{
// can't do, no valid DataSet constructor
public MyDataSet(DataSet ds) : base(ds) {}

// can't do
public Set(DataSet ds) {
base = ds;
}
}

MyDataSet myDS;
// can't do, can't upcast
myDS = SqlHelper.ExecuteDataSet("My_Proc");


This seems an obvious use of inheritance. What am I missing?

Thanks,
Mike
 
E

Einar Høst

Mike said:
I need to expand the DataSet class by inheriting from it and adding
functions that work on the data in the tables. However, since I can't
upcast how can I get my base DataSet object assigned an actual
DataSet?

e.g.

public class MyDataSet : DataSet
{
// can't do, no valid DataSet constructor
public MyDataSet(DataSet ds) : base(ds) {}

// can't do
public Set(DataSet ds) {
base = ds;
}
}

MyDataSet myDS;
// can't do, can't upcast
myDS = SqlHelper.ExecuteDataSet("My_Proc");


This seems an obvious use of inheritance. What am I missing?

Thanks,
Mike

Hmmm I take it you're using Microsoft's data access application block? The
"regular" (pure ADO.NET) way of filling a dataset would be instead to use a
DataAdapter, which takes a DataSet as input parameter to its Fill method,
like this:

// Assume that selectCmd is a useful SqlCommand object.
MyDataSet myDS;
DataAdapter da = new DataAdapter();
da.SelectCommand = selectCmd;
da.Fill(myDS);

As you can see, here upcasting is no problem whatsoever... what you should
do in case you need to use the application block, I dunno.

Regards,
Einar
 
D

Da~One

public class MyDataSet : DataSet
Hmmm I take it you're using Microsoft's data access application block? The
"regular" (pure ADO.NET) way of filling a dataset would be instead to use a
DataAdapter, which takes a DataSet as input parameter to its Fill method,
like this:

// Assume that selectCmd is a useful SqlCommand object.
MyDataSet myDS;
DataAdapter da = new DataAdapter();
da.SelectCommand = selectCmd;
da.Fill(myDS);

As you can see, here upcasting is no problem whatsoever... what you should
do in case you need to use the application block, I dunno.

You have your inheritence confused.

Your example and that of the OP are completely opposite in assignments
(which explains exactly why yours works and the OP's throws an invalid cast
exception).
 
G

Guest

----- Mike wrote: ----

I need to expand the DataSet class by inheriting from it and addin
functions that work on the data in the tables. However, since I can'
upcast how can I get my base DataSet object assigned an actua
DataSet

e.g

public class MyDataSet : DataSe

// can't do, no valid DataSet constructo
public MyDataSet(DataSet ds) : base(ds) {

// can't d
public Set(DataSet ds)
base = ds



MyDataSet myDS
// can't do, can't upcas
myDS = SqlHelper.ExecuteDataSet("My_Proc");


This seems an obvious use of inheritance. What am I missing

Hmmm..., without a copy constructor in DataSet you cannot do this. The closest you can get is by somehow trying to use DataSet.Copy() but even there you are stuck in a catch-22 trying to do this through inheritance. I don't know if there was any specific rational in not giving DataSet a copy constructor but let's assume there was. In this case I think you need to use a "Has-A" rather than an "Is-A" relationship..

public MyDataSe

private DataSet m_BaseDS

// Default constructio
public MyDataSet() { m_BaseDS = new DataSet();

// Construct a MyDataSet from an existing DataSe
public MyDataSet(DataSet ds) { m_BaseDS = ds;

// Get or Set the encapsulated DataSe
public DataSet DataSe

get { return m_BaseDS;
set { m_BaseDS = value;


// Expose/Forward methods and properties to encapsulated DataSet for convenience
// although this isn't absolutely necessary since we can get at the DataSet directly
public DataTableCollection Tables { get { return m_BaseDS.Tables; }

// and so on..


-- T
 
M

Mike

Since I really wanted to "be-a" dataset rather than "have-a" dataset I
decided on a variation of Einar's idea for the solution by adding a
static method to my DataSet decendent. For anyone googling this later
on...

public static MyDataSet Execute(string procName, params object[]
paramList)
{
MyDataSet ds = new MyDataSet();
using(SqlConnection cn = new SqlConnection(ConnectionString))
{
SqlCommand cmd = new SqlCommand(PrepareSql(procName, paramList),
cn);
using( SqlDataAdapter da = new SqlDataAdapter(cmd) ) {
cn.Open();
da.Fill(ds);
cn.Close();
return ds;
}
}
return ds;
}

which allows me to:

MyDataSet myDataSet = MyDataSet.Execute(Procedure, ParamList);

Thanks for the comments-
Mike


TB said:
----- Mike wrote: -----

I need to expand the DataSet class by inheriting from it and adding
functions that work on the data in the tables. However, since I can't
upcast how can I get my base DataSet object assigned an actual
DataSet?

e.g.

public class MyDataSet : DataSet
{
// can't do, no valid DataSet constructor
public MyDataSet(DataSet ds) : base(ds) {}

// can't do
public Set(DataSet ds) {
base = ds;
}
}

MyDataSet myDS;
// can't do, can't upcast
myDS = SqlHelper.ExecuteDataSet("My_Proc");


This seems an obvious use of inheritance. What am I missing?

Hmmm..., without a copy constructor in DataSet you cannot do this.
The closest you can get is by somehow trying to use DataSet.Copy() but
even there you are stuck in a catch-22 trying to do this through
inheritance. I don't know if there was any specific rational in not
giving DataSet a copy constructor but let's assume there was. In this
case I think you need to use a "Has-A" rather than an "Is-A"
relationship...
 
G

Guest

----- Mike wrote: ----

Since I really wanted to "be-a" dataset rather than "have-a" dataset
decided on a variation of Einar's idea for the solution by adding
static method to my DataSet decendent. For anyone googling this late
on..

public static MyDataSet Execute(string procName, params object[
paramList

MyDataSet ds = new MyDataSet()
using(SqlConnection cn = new SqlConnection(ConnectionString)

SqlCommand cmd = new SqlCommand(PrepareSql(procName, paramList)
cn)
using( SqlDataAdapter da = new SqlDataAdapter(cmd) )
cn.Open()
da.Fill(ds)
cn.Close()
return ds
}

return ds


[snip

Fair enough, but note that this is no solution to the problem you originally posed -- or perhaps I just misinterpreted it. You can always treat your derived class as a vanilla DataSet, fill it via a DataAdapter, etc. There is no trick here

What you cannot do, even with your solution, is accept a vanilla DataSet and somehow "bind" it to an instance of your derived class (short of tediously copying the data from it) as you showed in your original post

-- T
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top