2009-01-27 14 views
7

¿Hay una manera relativamente directa de obtener la intersección de dos tablas de datos en .NET?Encontrar la intersección de dos tablas de datos .NET

Puedo pensar en las formas obvias (iterando sobre ambas tablas en O (n^2)), pero me gustaría algo un poco más elegante si está disponible. Sospecho que puede haber una manera inteligente que no estoy viendo. La legibilidad y la capacidad de mantenimiento son importantes, por supuesto, así que estoy tratando de mantenerme alejado de cualquier cosa demasiado "astuta".

¿Alguna buena idea?

EDIT: Parece que Bryan Watts tiene una muy buena solución para 3.5, pero por desgracia estoy en .NET 2.0

+0

¿Cuál es la fuente de las tablas de datos? Si son de un servidor SQL, ¿por qué no hacerlo allí? – toad

Respuesta

11

Con .NET 3.5 (que debería haber mencionado.):

using System.Data; 

public static class DataTableExtensions 
{ 
    public static IEnumerable<DataRow> Intersect(this DataTable table, DataTable other) 
    { 
     return table.AsEnumerable().Intersect(other.AsEnumerable()); 
    } 

    public static IEnumerable<DataRow> Intersect(this DataTable table, DataTable other, IEqualityComparer<DataRow> comparer) 
    { 
     return table.AsEnumerable().Intersect(other.AsEnumerable(), comparer); 
    } 
} 
+0

Esta es una solución genial. +1 – Perpetualcoder

+0

Esto no resuelve mi problema en particular, per se, pero es una solución tan elegante a la pregunta en general, que probablemente lo hace útil para las personas que buscan en este problema, tiene que obtener el estado "aceptado". (Desearía que pudiera compartirlo con su otra respuesta ... sería bueno tener ambas). – Beska

2

Vio este ejemplo en MSDN que puede serle útil. Está usando la sintaxis LINQ.

DataSet ds = new DataSet(); 
ds.Locale = CultureInfo.InvariantCulture; 
FillDataSet(ds); 

DataTable orders = ds.Tables["SalesOrderHeader"]; 
DataTable details = ds.Tables["SalesOrderDetail"]; 

var query = 
    from order in orders.AsEnumerable() 
    join detail in details.AsEnumerable() 
    on order.Field<int>("SalesOrderID") equals 
     detail.Field<int>("SalesOrderID") 
    where order.Field<bool>("OnlineOrderFlag") == true 
    && order.Field<DateTime>("OrderDate").Month == 8 
    select new 
    { 
     SalesOrderID = 
      order.Field<int>("SalesOrderID"), 
     SalesOrderDetailID = 
      detail.Field<int>("SalesOrderDetailID"), 
     OrderDate = 
      order.Field<DateTime>("OrderDate"), 
     ProductID = 
      detail.Field<int>("ProductID") 
    }; 


foreach (var order in query) 
{ 
    Console.WriteLine("{0}\t{1}\t{2:d}\t{3}", 
     order.SalesOrderID, 
     order.SalesOrderDetailID, 
     order.OrderDate, 
     order.ProductID); 
} 
1

protegida void Page_Load (object sender, EventArgs e) {

DataTable dt1 = new DataTable(); 

    dt1.Columns.Add("ColX", typeof(int)); 

    DataTable dt2 = new DataTable(); 

    dt2.Columns.Add("ColX", typeof(int)); 

    for (int i = 1; i <= 5; i++) 
    { 
     DataRow row = dt1.NewRow(); 

     row["ColX"] = 5 + i; 

     dt1.Rows.Add(row); 

     row = dt2.NewRow(); 

     row["ColX"] = 9 + i; 
     dt2.Rows.Add(row); 
    } 


    intesect(dt1, dt2); 

} 


public void intesect(DataTable contacts1, DataTable contacts2) 
{ 
    var contacts = contacts1.AsEnumerable().Intersect(contacts2.AsEnumerable(), DataRowComparer.Default); 


    foreach (DataRow row in contacts) 
    { 
     Response.Write(row["ColX"]); 
    } 
} 
Cuestiones relacionadas