所以我有两个DataTable,都来自同一个ODBC数据源。一个有销售行(Estado =' VENTAS')和另一个用于Estado =' EXIST' (数据库为每次销售创建行对,一个表示销售信息,另一个表示商店存款的库存变动信息,因此为了知道哪个商店进行了销售,我必须匹配每个VENTAS行到相应的EXIST行[通过' Documento' ID字段]并从存在的行中获取" Deposito"值。
我构建了这个查询来做到这一点(我使用的ODBC驱动程序不允许连接,所以在Linq中这样做是下一个最好的事情)
DataTable dtResult = new DataTable();
dtResult.Columns.Add("Documento", typeof(Int64));
dtResult.Columns.Add("Fecha", typeof(DateTime));
dtResult.Columns.Add("Articulo", typeof(string));
dtResult.Columns.Add("Deposito", typeof(string));
dtResult.Columns.Add("ImpDMn", typeof(decimal));
dtResult.Columns.Add("Cantidad", typeof(decimal));
dtResult.Columns.Add("Partida", typeof(string));
var result = from dataRows1 in VentasDT.AsEnumerable() //VentasDT is the DataTable with the VENTAS data
join dataRows2 in ExistDT.AsEnumerable() // ExistDT is the DataTable with the EXIST data
on dataRows1.Field<Int64>("Documento") equals dataRows2.Field<Int64>("Documento")
select dtResult.LoadDataRow(new object[]
{
dataRows1.Field<Int64>("Documento"),
dataRows1.Field<DateTime>("Fecha"),
dataRows1.Field<string>("Articulo"),
dataRows2.Field<string>("Deposito"),
dataRows1.Field<decimal>("ImpDMn"),
dataRows1.Field<decimal>("Cantidad"),
dataRows1.Field<string>("Partida"),
}, false);
result.CopyToDataTable();
并且它可以工作但由于某种原因它复制一些行。 我检查了重复的行,它们彼此相同。他们的文档编号是相同的(每个Documento编号只有一个VENTAS和一个EXIST行,包括这些重复项)所以我不知道他们为什么会重复。我检查了数据表I加入的来源,同样,每个重复项只有一条相应的行。 EXIST表大于VENTAS表(它还记录不是销售的商店之间的转移)但是连接表比任何一个都大(但没有两者一样大)
VENTAS: 85123
EXIST: 116857
JOIN: 141287
我的查询有问题吗?我是否应该包含一些GROUP BY子句或.Distinct,或者这个结构(我已经看到它应该模仿左连接)是否足够?
答案 0 :(得分:1)
由于您进行此连接的唯一原因是从"Deposito"
获取ExistDT
字段的值,您可以使用字典查找替换连接。以下是如何做到这一点:
var depositoPorDocumento = ExistDT.AsEnumerable().ToDictionary(
dr => dr.Field<Int64>("Documento"),
dr => dr.Field<string>("Deposito")
);
foreach (var vr in VentasDT.AsEnumerable()) {
Int64 id = Field<Int64>("Documento");
string deposito;
if (!depositoPorDocumento.TryGetValue(id, out deposito)) {
continue;
}
dtResult.LoadDataRow(new object[]
{
id,
vr.Field<DateTime>("Fecha"),
vr.Field<string>("Articulo"),
deposito,
vr.Field<decimal>("ImpDMn"),
vr.Field<decimal>("Cantidad"),
vr.Field<string>("Partida"),
}, false);
}
result.CopyToDataTable();