I notice you're using strings as the join keys. Perhaps the string comparison is different between the environments (access vs .net). Access may use a case-insensitive compare, while .net's default is case-sensitive.
To make .net use a case-insensitive compare, here's the first query:
var results = data1.AsEnumerable()
.Join(
data2.AsEnumerable(),
row1 => row1.Field<String>("proId"),
row2 => row2.Field<String>("proId2"),
(row1, row2) => row1.ItemArray.Concat(row2.ItemArray).ToArray(),
StringComparer.InvariantCultureIgnoreCase); //and now caps are ignored.
and second query:
var results = data1.AsEnumerable()
.GroupJoin(
data2.AsEnumerable(),
row1 => row1.Field<String>("proId"),
row2 => row2.Field<String>("proId2"),
(row1, row2s) => new {Row1 = row1, Row2s = row2s},
StringComparer.InvariantCultureIgnoreCase)
.SelectMany(
x => x.row2s.DefaultIfEmpty(null)),
(x, row2) => row2 == null ? x.Row1.ItemArray : x.Row1.ItemArray.Concat(row2.ItemArray).ToArray()
);