给定一个 DataSet,我将把 DataTables[1-n] 加入 DataTable[0]。我创建了一个带有签名的方法,如下所示:
public DataTable LeftJoin(DataSet ds, params JoinKey[] JoinKey)
笔记:
- 返回类型是 DataTable,它是生成的左连接。
- DataSet ds 是用于连接的 DataTables 的集合。
- JoinKey 是一个具有两个公共属性的对象:Type DataType 和 string Name。此集合包含要在联接中使用的每个字段的类型/名称。
以下是两个片段(片段 1和片段 2)片段 1 正常工作。唯一的问题是 GroupJoin 的第二个和第三个参数是硬编码的:
// hard-coded:
br => new
{
zip = br.Field<string>("ZipCode"),
store =br.Field<double>"StoreID")
},
jr => new
{
zip = jr.Field<string>("ZipCode"),
store = jr.Field<double>("StoreID")
}
以上是不可取的。相反,我想使用我的“JoinKey”对象来动态设置我想要加入的字段(即 ZipCode 和 StoreID)。我在Snippet 2中尝试过这个。但是,首先,请参阅片段 1。
片段 1(工作,硬编码):
var dtBase = ds.Tables[0].AsEnumerable();
for (int i = 1; i < ds.Tables.Count; i++)
{
var query = dtBase.GroupJoin(ds.Tables[i].AsEnumerable(),
br => new
{
zip = br.Field<string>("ZipCode"),
store = br.Field<double>("StoreID")
},
jr => new
{
zip = jr.Field<string>("ZipCode"),
store = jr.Field<double>("StoreID")
},
(baseRow, joinRow) => joinRow.DefaultIfEmpty()
.Select(row => new
{
flatRow = baseRow.ItemArray.Concat((row == null) ? new object[ds.Tables[i].Columns.Count] : row.ItemArray).ToArray()
})
).SelectMany(s => s);
[... create a DataTable with the resulting left join, etc. ...]
}
注意:变量“flatRow”存储左连接数据的对象数组;稍后在方法中将其添加到 DataRowCollection(未显示)。
片段 2(不工作;但是没有抛出错误):
var dtBase = ds.Tables[0].AsEnumerable();
for (int i = 1; i < ds.Tables.Count; i++)
{
var query = dtBase.GroupJoin(ds.Tables[i].AsEnumerable(),
or => KeySelector(or, JoinKey),
ir => KeySelector(ir, JoinKey),
(baseRow, joinRows) => joinRows.DefaultIfEmpty()
.Select(joinRow => new
{
flatRow = baseRow.ItemArray.Concat((joinRow == null) ? new object[ds.Tables[i].Columns.Count] : joinRow.ItemArray).ToArray()
})
)
.SelectMany(s => s);
[... create a DataTable with the resulting left join, etc. ...]
}
这是上面使用的KeySelector函数(请参阅内联注释):
private IEnumerable KeySelector(DataRow dr, params JoinKey[] JoinKey)
{
List<object> gl = new List<object>();
foreach (JoinKey jk in JoinKey)
{
// note that I did try to mimic the 'hard-coded' approach from Snippet 1:
// this does not work:
// gl.Add(dr.Field<jk.DataType>(jk.Name)); --> it does not like <jk.DataType>
// I 'hacked' around it by using the following:
gl.Add(dr[dr.Table.Columns.IndexOf(jk.Name)]);
}
return gl;
}
片段 2仅返回来自 DataTable[0] 的数据。DataTable[1-n] 中的所有数据(如果存在)都没有连接到变量“flatRow”中。不过,有趣的是,我确实得到了数组中正确数量的元素。我知道这与 KeySelector 方法有关,但是(显然)我不知道问题是什么。
如果有人需要更多信息,请告诉我。非常感谢您的帮助...
谢谢,
泰勒