I'll preface this question by sharing that I have read the MSDN site related to LINQ (which is geared towards database usage with known column names and not in-memory datasets and datatables) and have spent maybe 20 hours searching various forums for a solution for what I have to solve.
I have an
c# Winforms application which will accept a CSV file and load the data into a datatable. The datatable column names are read and populated into another datatable that serves to map the source datatable to the normalized final datatable. The user is presented with a screen where they provide input on which source column matches which destination column.
Problem
How to copy only the columns from the source table needed to the destination table using the mapping table to tell what is supposed to go where. In SQL I would do this via dynamic SQL like:
DECLARE @sql nvarchar(4000)
SELECT @sql = 'SELECT ' + STUFF((SELECT ',' + ISNULL(m.src,'') FROM tbl_map m FOR XML PATH('')),1,1,'') + ' FROM tbl_src'
INSERT INTO target_table
EXEC(@sql)
Again, nothing I've read anywhere has dealt with the use of datatable as the source where the column names are not known in advance.
Sample Source:
-----------------------------------------------------------------------
| FName | LName | DOB | SSN | Sex | LicNbr | State |
| Bob | Smith | 19230105 | 123456789 | M | N4257665 | NJ |
| Jane | Doe | 19670530 | 000000000 | F | 12457890 | PA |
-----------------------------------------------------------------------
Sample Mapping:
--------------------------
| Target | Source |
| first_name | FName |
| last_name | LName |
| license_state | State |
| license_id | LicNbr |
--------------------------
Sample Output Expected:
-------------------------------------------------------
| first_name | last_name | license_state | license_id |
| Bob | Smith | NJ | N4257665 |
| Jane | Doe | PA | 12457890 |
-------------------------------------------------------
Here are the dataset/datatables involved:
DataTable dt = new DataTable("dt_map");
DataColumn dc = new DataColumn("source", typeof(string));
dc.DefaultValue = string.Empty;
dt.Columns.Add(dc);
dc = new DataColumn("target", typeof(string));
dc.DefaultValue = string.Empty;
dt.Columns.Add(dc);
dt.BeginLoadData();
dt.Rows.Add("first_name", "");
dt.Rows.Add("last_name", "");
dt.Rows.Add("license_state", "");
dt.Rows.Add("license_id", "");
dt.EndLoadData();
ds_mstr.Tables.Add(dt.Copy());
dt = new DataTable("dt_final");
dc = new DataColumn("first_name", typeof(string));
dc.DefaultValue = string.Empty;
dt.Columns.Add(dc);
dc = new DataColumn("last_name", typeof(string));
dc.DefaultValue = string.Empty;
dt.Columns.Add(dc);
dc = new DataColumn("license_state", typeof(string));
dc.DefaultValue = string.Empty;
dt.Columns.Add(dc);
dc = new DataColumn("license_id", typeof(string));
dc.DefaultValue = string.Empty;
dt.Columns.Add(dc);
ds_mstr.Tables.Add(dt.Copy());
Again, the
source column names are unknown until imported from the file and will vary in naming and quantity. Assume everything is being treated as a string for the sake of simplicity. Thank you to whoever can provide a solution/guidance and even more thanks if an explanation can come with the answer so I can learn something along the way and be a better developer for it!
What I have tried:
Searching for solutions or anything that might be anywhere close to what I'm looking for (LINQ query using dynamic columns names mapped between two tables using a table that maps the column names between the two tables).