2014-10-10 98 views
1

所以我有两个DataTables,都取自同一个ODBC数据源。一个销售行(Estado ='VENTAS'),另一个销售行Estado ='EXIST'(数据库为每个销售创建行对,一个表示销售信息,另一个表示销售存款的库存移动信息,所以在为了知道什么商店进行了销售,我必须将每个VENTAS行匹配到相应的EXIST行['Documento'ID字段],并从Exist行中获取“Deposito”值。Linq查询返回重复项

我建立了这个查询做到这一点(我使用不允许连接,以便做Linq中是退而求其次的ODBC驱动程序)

  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行,包括这些重复项),所以我不知道他们为什么重复。我检查了我正在加入的源数据表,同样,每个副本只有一条对应的行。该存在的资料表比VENTAS表较大(它还记录转移不属于销售店之间),但连接表大于或者(尚未大如两个组合)

VENTAS: 85123 
EXIST: 116857 
JOIN: 141287 

有什么问题用我的查询?我是否应该包含一些GROUP BY子句或.Distinct,或者该结构(就我所见,应该模仿一个左连接)是否足够?

+0

能代表在'EXIST'表调剂记录有自己的'场Documento'等于从'VENTAS'了'Documento'场? – dasblinkenlight 2014-10-10 15:45:05

+0

编号转移拥有自己独特的Documento值,在Ventas表中没有找到互补,就我所见,连接表中的每个副本都有一个Documento值,它显示在原始的Ventas表中(因此不是传输).. – ConnorU 2014-10-10 15:58:56

回答

1

由于您正在进行此连接的唯一原因是从ExistDT获取"Deposito"字段的值,因此可以用字典查找替换连接。这里是你如何能做到这:

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(); 
+0

您的解决方案给我很多语法错误:对ExistTD.ToDictionary()没有定义和扩展方法(...)。 foreach语句无法对foreach上的Datatable(...)进行操作(VentasDT中的var vr;以及!depositoPorDocumento.TryGetValue(id,out deposito)上的无效参数...? – ConnorU 2014-10-10 16:31:28

+0

@ConnorU我不确定什么是'VentasDT'和'ExistTD',所以我跳过了'.AsEnumerable()'调用,我把它们加回去了,看看这个编译。 – dasblinkenlight 2014-10-10 16:33:24

+0

你的解决方案编译但崩溃了 - 这表明我犯了我的错误:每个Documento可能包含多于一行的产品,如果有多个产品被出售,我通过Articulo ID订购我的表格,然后通过Document订购我们的表格,以便它们看起来不会超过一个,当我进行加入时,该程序将第一个Articulo它发现的信息,所以它似乎是一个重复,但它是一个替代... 感谢您的回答,我的问题是错误的,我现在需要编辑它 – ConnorU 2014-10-10 16:43:40