tags:

views:

774

answers:

4

Greetings Guru's

I have a peculiar problem with TableAdapters and the Fill Method. I have a bunch of autogenerated TableAdapters as a result of binding an app to a DataSource. They are bound to controls on my form and work as expected.

Now I need to call the fill method on the TableAdapters from time to time and I want to do It programatically (TableAdapters["Name"].Fill(myDataSet["Name_Table"]);) instead of literally (TableAdapter_Name.Fill(myDataSet.Name_Table);

The Idea is to pass a string to a method that can call the targeted TableAdapter by parsing the string to recognize the desired object. I've often wished that C# supported creating dynamic statements/methods (from strings) that can be executed like a regular statement.

Is this possible? (If not it seems like I'll be doing a LOT of literal typing to represent all of my TableAdapters and when I do a lot of literal typing of strings in my code it's a RED FLAG that I'm doing something wrong"

Help, Zion

NameTableAdapter.Fill(myDataSet.Name); StateTableAdapter.Fill(myDataSet.State); CityTableAdapter.Fill(myDataSet.City);

A: 

You might create a Dictionary<DataTable, TableAdapterWrapper> that associates your datatables with their table adapters. The wrapper class can use reflection to call the Fill method (since, if I'm not mistaken, the table adapters don't implement a common interface or inherit from a common base class).

public class TableAdapterWrapper
{
    object tableAdapter;
    DataTable table;

    public TableAdapterWrapper(object tableAdapter, DataTable table)
    {
        this.tableAdapter = tableAdapter;
        this.table = table;
    }

    public void Fill()
    {
        var methodInfo = tableAdapter.GetType().GetMethod("Fill");
        methodInfo.Invoke(tableAdapter, new object[] { table });
    }
}
Aviad P.
A: 

Instead of using names you can use enums to index array of Adapters like the following

enum Types
{
Adapter1,Adapter2
}
SqlDataAdapter [] Adapters = new SqlDataAdapter();
adapters[Types.Adpter1] = adapter1;
adapters[Types.Adpter1] = adapter2;

//call
Adapters[Types.Adpter1].Fill(table);
Ahmed Said
A: 

take a look @ CS-Script this is free library for scripting with c# syntax .using this library you can write a method which will get a string and run it as statement . this is the solution I use for creating dynamic statements .

Asha
This is COOL!, I did not know this existed, I've been an autoIT and VBSCRIPT guy for years and wanted more PowER! (PowerShell is clunky slow, F# is inmature) This is what I've been looking for. Thanks for that tip. Wheel are turning now. WoW!
Zion
it is really powerful and easy to use ,happy that your problem is solved .BTW if you liked it or it solved your problem you can mar it as your answer or vote to it .thanks
Asha
I have not had an oppurtunity to implement the solutions offered as yet. CS-Script won't be beacause it's a deployable app.
Zion
A: 

Essentially you are asking for something like the javascript eval(...) statement. No, C# doesn't have that, and for good reason. Among other things, it would have to fire up a new compiler for every instance of this at runtime. There may be some libraries or external tools that provide this type of functionality, but I would be very wary of using them for something like this.

If these TableAdapters are on a form, then they are instance members and you could use the Type.GetField method to find the adapter and then the Type.GetMethod to find the Fill method on the TableAdapter to invoke.

But my question is, why do you need to do this? To me, the red flag is the fact that somebody is trying to create such a messy abstraction over a data layer. Things to consider:

  • Most databases have very few tables that are small enough to dump all rows from without killing both database and app performance. You should almost never use the parameterless Fill/GetData methods.
  • Using Reflection means you don't get any compile-time checking, and unless it's very tightly controlled (i.e. as part of some DI framework), it's likely to lead to mysterious, hard-to-debug errors down the road.
  • The Fill method itself takes a typed parameter, so if you try to write a "generic" fill method, it makes it possible for someone to write code that passes an incorrect table type, which could lead to all sorts of fun and unpredictable problems.
  • TableAdapters in general are - how should I say this - not exactly deprecated, but not the preferred means of data access today. Entity Framework and Linq to SQL are much more attractive options. Unless you've inherited this DAL from a previous designer, why use it at all?

I think you should explain more about your problem domain. I am willing to bet that there is a better design available for your particular requirements.

Aaronaught
I appreciate your feedback bro. Thanks
Zion