Reputation: 1185
Similar question exists but solution does not apply. I'm finishing a small program that allows user to import 2 data tables and join to get results. Here's relevant code:
List<DataRow> list1 = ds1.Tables[0].AsEnumerable().ToList<DataRow>();
List<DataRow> list2 = ds2.Tables[0].AsEnumerable().ToList<DataRow>();
var v = (from t1 in list1
join t2 in list2
on t1.Field<string>(ds1ColInx) equals t2.Field<string>(ds2ColInx)
select new
{
t1,
t2
}).ToList();
But this can't be fed into DataGridView
, quite obviously. Now, I also have a string array
of column names and column indexes for each table and column that user wants to see. How can I plug that into select
statement?
Upvotes: 1
Views: 4670
Reputation: 26917
I would suggest converting v
to a DataTable
and copying the columns desired. Using cols
as your desired columns:
string[] cols;
var dt = new DataTable();
var t1cols = ds1.Tables[0].Columns.Cast<DataColumn>().Select(dc => dc.ColumnName).ToHashSet();
var tcols = t1cols.Cast<DataColumn>().Union(ds2.Tables[0].Columns.Cast<DataColumn>()).ToDictionary(dc => dc.ColumnName);
foreach (var cname in cols)
dt.Columns.Add(new DataColumn(cname, tcols[cname].DataType));
foreach (var vr in v) {
var nr = dt.NewRow();
foreach (var cname in cols)
nr[cname] = t1cols.Contains(cname) ? vr.t1[cname] : vr.t2[cname];
dt.Rows.Add(nr);
}
Now you can just assign dt
to GridView.DataSource
.
Note that bad things will happen if t1
and t2
have any columns with the same name, in which case you should rename them all with a table prefix in t1cols
, tcols
and when adding them to dt.Columns
.
Upvotes: 1
Reputation: 11433
You can bring in the Microsoft-developed "System.Linq.Dynamic" library to accomplish your goal. You can find it on NuGet here:
http://www.nuget.org/packages/System.Linq.Dynamic/
And the source is here:
https://github.com/kahanu/System.Linq.Dynamic
Then reference System.Linq.Dynamic, and you will have access to new extension methods that accept strings rather than expressions.
I have only every used it with the lambda-based LINQ extension methods, which enable you to do things like this:
.Select("column1, column2, column3").ToList();
I have attempted to rewrite your query using the lambda syntax below, although it is untested:
var v = list1.Join(
list2,
t1 => t1.Field<string>(ds1ColInx),
t2 => t2.Field<string>(ds2ColInx),
(t1, t2) => new {t1, t2});
v.Select(columnList).ToList();
Note: in this situation, you may need to play around a bit with your column strings (for instance, I think you'll need to prefix them with "t1" or "t2" depending on which table they are actually in).
Upvotes: 1