views:

53

answers:

1

I have an ASP.NET (3.5) page that allows a user to upload an Excel 2003 file with multiple sheets and that data is inserted into staging tables in the database. The mapping of database tables/columns to Excel sheets/columns is specified in an XML file. I use LINQ to SQL to send the data to the database.

ImportTablesDataContext db = new ImportTablesDataContext();
tblImportLoan loan; // class defined by LINQ to SQL

// iterate through each row of data from the Excel worksheet called Loans
foreach (DataRow dr in _data.Tables[ExcelSheetName].Rows)
{
  loan = new tblImportLoan();

  // iterate through each column in the mapping for the Loans worksheet
  foreach (... column in mapping for this worksheet ...)
    loan.GetType().GetProperty(column.DBName).SetValue(loan, GetValue(column, dr), null);

  db.tblImportLoans.InsertOnSubmit(loan);
}

I repeat most of this code for each of the 5 worksheets. I would like to iterate through the set of 5 tables defined in the mapping - but I cannot figure out how to make the hard-coded class names / methods / properties dynamic (lines 2, 7, and 13 above). This would allow me to avoid referencing the table names outside of the XML file.

Any suggestions?

EDIT: Here is what I'm looking for... but I don't know how to do lines 5 and 8.

foreach (... table in mapping ...)
{
  foreach (DataRow dr in _data.Tables[table.ExcelSheetName].Rows)
  {
    obj = new <LINQ constructor derived from table name>;
    foreach (... column in mapping ...)
      obj.GetType().GetProperty(column.DBName).SetValue(obj, GetValue(column, dr), null);
    db.<LINQ property derived from table name>.InsertOnSubmit(obj);
  }
}
+2  A: 

I think you could do it by retrieving the Table<TEntity> objects directly from the DataContext. First, you need to wrap your code in a generic method:

public void DoWorkFor<TEntity>()
{
    ImportTablesDataContext db = new ImportTablesDataContext();
    Table<TEntity> table = db.GetTable<TEntity>();

    // iterate through each row of data from the Excel worksheet called Loans
    foreach (DataRow dr in _data.Tables[ExcelSheetName].Rows)
    { 
        entity = new TEntity();

        // iterate through each column in the mapping for the Loans worksheet
        foreach (... column in mapping for this worksheet ...)
        {
            entity.GetType().GetProperty(column.DBName)
                .SetValue(entity, GetValue(column, dr), null);
        }

        table.InsertOnSubmit(entity);
    }
}

Then, somewhere else in your program, you need to call this method and supply the appropriate entity type:

DoWorkFor<tblImportLoan>();
DoWorkFor<tblOtherType1>();
DoWorkFor<tblOtherType2>();
DoWorkFor<tblOtherType3>();
DoWorkFor<tblOtherType4>();

Is this close to what you're looking for? Add a comment if not.

Damian Powell
Thanks Damian! I tried this out and it works - had to tweak the method declaration a bit by adding "where TableEntity : class, new()". Thank you for the suggestion. I'm going to see if I can find out a way to derive the type using a string - if that works I'll be estatic.
Mayo
Looks like today's my day... I can loop over the tables defined by LINQ - if I find a match in the XML mapping data I call DoWorkFor with that table's type. In theory. The key is db.Mapping.GetTables().
Mayo
Cool! Glad it was useful.
Damian Powell