recorrer query framework example copytodatatable consulta c# linq-to-sql .net-3.5 datatable linq-to-objects

c# - query - Posible escribir una unión entre Sql y DataTable utilizando Linq?



linq to datatable c# example (3)

Por lo general, abordo todo esto en un proceso almacenado para mayor eficiencia.

Agregue un campo de identidad a su tabla de destino para identificar de manera exclusiva los registros, luego use una consulta como esta:

DELETE d FROM DestinationTable d JOIN ( Select CompanyID, CustomerID, Min(UniqueID) AS FirstRecID FROM DestinationTable GROUP BY CompanyID, CustomerID) u on u.CompanyID=d.CompanyID AND u.CustomerID=d.CustomerID WHERE d.UniqueID <> u.FirstRecID

Tengo un proceso que extrae información del cliente de múltiples bases de datos (MySql) en base a una marca de tiempo. Guardo esta información en una DataTable . La tabla de datos representa las actualizaciones de la información del cliente existente, así como la nueva información del cliente.

Quiero eliminar cualquier duplicado en la base de datos de destino (SqlServer) basado en un valor constante, CompanyID y CustomerID . Entonces, pensé que una unión me daría los RecordIDs de los dupes en el DB de destino, pasar el List<int> (o algún mecanismo de recolección) al método DELETE .

Lo que tengo:

using (var context = new DataContext(SqlConnection)) { var tblSource = context.GetTable<tblCustomerInfo>(); var dupeIDs = from currCust in tblSource join newCust in myTable.AsEnumerable() on currCust.CompanyID equals newCust.Field<string>("CompanyID") where currCust.CustomerID.Equals(newCust.Field<int>("CustomerID") select currCust.RecordID; }

Esto obviamente no funciona. Voy a actualizar con los mensajes de error exactos en un momento, pero esto no se compila.

Primero, ¿mi sintaxis de unión es correcta para lo que quiero lograr?

En segundo lugar, ¿cómo puedo escribir este Linq para unirme entre una DataTable y la base de datos SqlServer de destino?

Pospuesto : ¿es posible, una vez que tenga una colección de RecordIDs dupe, usar Linq para ELIMINAR registros de la base de datos de destino?

Editar Para aclarar el proceso, tengo tablas de datos entrantes como esa y contenidas en un DataSet :

Table1 CompanyID CustomerID Field1 Field2 .... 1 5 ... ... 1 15 ... ... Table2 CompanyID CustomerID Field1 Field2 .... 10 125 ... ... 10 145 ... ...

Que irán todos a una única base de datos:

Destination DB CompanyID CustomerID Field1 Field2 .... 1 5 ... ... 1 15 ... ... 1 27 ... ... 5 15 ... ... 10 125 ... ... 10 145 ... ... 11 100 ... ...

Entonces, en este caso, eliminaría de la tabla de destino los elementos que coinciden con las tablas 1 y 2. La base de datos de destino crecerá constantemente, por lo que no parece posible crear una lista de ID de cliente. Sin embargo, espero que las importaciones diarias de información del cliente nueva y actualizada sean relativamente pequeñas (en cientos, tal vez cerca de 1000 registros).

Si no puedo escribir una sola unión, ¿qué otro método para completar este proceso sería apropiado? Estoy intentando descubrir algo, ya que parece que no puedo mezclar Linq-to-Sql y Linq-to-Objects.

¿Es posible mapear de algún modo mi tabla de datos en el mapa de datos de la entidad, tbl_CustomerInfo , llenando una var que de otro modo sería inmutable, y luego realizar la unión?

Actualizar

Esto es lo que he logrado en este punto y obtengo los resultados que espero de los dupes :

using (DataContext context = new DataContext(SqlConnection) { var custInfo = context.GetTable<tbl_CustomerInfo>(); string compID = ImportCust.Rows[0]["CompanyID"].ToString(); var imports = from cust in ImportCust.AsEnumerable() select cust.Field<int>("CustomerID"); var dupes = from cust in custInfo join import in imports on cust.CustomerID equals import where cust.CompanyID == compID select cust; custInfo.DeleteOnSubmit(/* what goes here */); context.SubmitChanges(); }

Mi pregunta ahora es, ¿qué entra en el DeleteOnSubmit(...) ? Siento que me he acercado tanto para frustrarme.


Alternativamente, puede crear dos listas de List<int> , que contengan id de sus dos fuentes, luego use el operador Intersect LINQ para encontrar los elementos comunes.

List<int> a = new List<int>{1,2,3,4,5,6,8, 10}; List<int> b = new List<int>{1,2,99,5,6,8, 10}; var c= a.Intersect(b); //returns the items common to both lists


Esto es lo que tengo que funciona:

using (DataContext context = new DataContext(SqlConnection) { var custInfo = context.GetTable<tbl_CustomerInfo>(); string compID = ImportCust.Rows[0]["CompanyID"].ToString(); var imports = from cust in ImportCust.AsEnumerable() select cust.Field<int>("CustomerID"); var dupes = from import in imports join cust in custInfo on import equals cust.CustomerID where cust.CompanyID== pivnum select cust; var records = dupes.GetEnumerator(); while (records.MoveNext()) { custInfo.DeleteOnSubmit(records.Current); } context.SubmitChanges(); }

Si hay un método más eficiente, estoy interesado en las opciones.