Generic function to populate a typed dataset?



  • Afternoon all.

    I have a quick question, I am writing a small app (C#) at the moment and need a function which can be passed a typed dataset will populate it and pass it back (Not a problem) however I want to re-use this function for different typed datasets... thats where I run into issues the method signature at the moment is:

    <FONT color=#0000ff size=2><FONT color=#0000ff size=2>

    public</FONT></FONT><FONT size=2> </FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>void</FONT></FONT><FONT size=2> PopulateDataset(</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>string</FONT></FONT><FONT size=2> sql, </FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>ref</FONT></FONT><FONT size=2> </FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>DataSet</FONT></FONT><FONT size=2> ds, </FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>bool</FONT></FONT><FONT size=2> isSproc, </FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>Enums</FONT></FONT><FONT size=2>.</FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>DataBases</FONT></FONT><FONT size=2> Database, </FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>List</FONT></FONT><FONT size=2><</FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>DataParamater</FONT></FONT><FONT size=2>> Paramaters)</FONT>

    <FONT size=2> Now I can create a normal dataset pass that in and have it populated now problem, but I cant get it to work with a typed dataset, obvioulsly because a typed dataset derived from system.data.dataset but isnt actually that type, one suggestion that I have been goven is to write one function for every dataset and for this app it wouldnt be too much work, but I want this to be re-usable so I could do with finding a solution... if there is one?</FONT>

    <FONT size=2>Thanks in advance!</FONT>

    <FONT size=2> 

    </FONT>


  • I have (kind of) found a way that this will work, although its not great and Id prefer either a better way or validation from some one who knows more about it that this is the right way.

     

    Basically what I have is the same function sig as before, but when I call it Im doing this (DsNames etc changed):

     DataSet ds = (DataSet)new TypedDataset();

    Then Im passing this into the PopulateDataSet function and then casting the value back:

    PopulateDataSet("SELECT * FROM FOOBAR", ref ds, .......); 

    TypedDataSet ds1 = (TypedDataSet) ds;

     

    This works but is far from ideal in my mind, I want to be able to pass in any typed dataset to the populateDataSet function and get the same type back... however Im not convinced that this is possible?



  • <FONT size=2>

    <FONT color=#0000ff>void</FONT> PopulateDataset<T> (</FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>string<FONT color=#000000 size=2> sql, </FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>ref</FONT></FONT><FONT color=#000000 size=2> T</FONT><FONT color=#000000 size=2> ds, </FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>bool</FONT></FONT><FONT color=#000000 size=2> isSproc, </FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>Enums</FONT></FONT><FONT color=#000000 size=2>.</FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>DataBases</FONT></FONT><FONT color=#000000 size=2> Database, </FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>List</FONT></FONT><FONT color=#000000 size=2><</FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>DataParamater</FONT></FONT><FONT color=#000000 size=2>> Paramaters</FONT></FONT></FONT><FONT size=2>) </FONT><FONT color=#0000ff size=2><FONT color=#0000ff size=2>where</FONT></FONT><FONT size=2> T : </FONT><FONT color=#2b91af size=2><FONT color=#2b91af size=2>DataSet</FONT></FONT>

    <FONT color=#2b91af size=2><FONT color=#2b91af size=2><FONT color=#000000>I do have to ask one question...  How can you possible "re-use" PopulateDataSet if it might fill any of number of different, but incompatible, types of DataSets?  It sounds to me like the method will be a huge switch.  Making one method for each type would probably end up being less code and more readable.</FONT>

    </FONT></FONT>


  • @Jaime said:

    It sounds to me like the method will be a huge switch.  Making one method for each type would probably end up being less code and more readable.
    Not sure about C#, but in C++ I'd probably make a helper template class that has a single method (get()) that returns a value of that datatype, since IIRC you can have type specific template-class members.



  • @Lingerance said:

    @Jaime said:
    It sounds to me like the method will be a huge switch.  Making one method for each type would probably end up being less code and more readable.
    Not sure about C#, but in C++ I'd probably make a helper template class that has a single method (get()) that returns a value of that datatype, since IIRC you can have type specific template-class members.

    With the template solution, you actually get to write an independant method body for the implementation of each type.  With the C# generic approach, you only get to write the method body once and it is used for any type that is passed in.  The easiest way to write this in C# is to simply make a method (or a whole class) for each type.

    Come to think of it, the OP is re-inventing strongly-type DataSets, but poorly.  It would be far easier to create an XML file that describes the various loading behaviors of the DataSet and let Visual Studio turn it into two thousand lines of reliable, convenient, template-based code.



  • This is now sorted, we have a single method for doing our dataaccess which passes back typed datasets based on paramaters passed to it (without having a huge switch statement :) )

     Thanks for the help guys, the comments have helpped a lot!

     


Log in to reply