Select Join ricorsiva in c# con Linq

imagesOggi ho avuto bisogno di creare un extension method per poter selezionare in modo ricorsivo i figli di figli di un item padre in una lista. 🙂

Ecco una soluzione pulita per fare gerarchica ricorsiva join in LINQ e C#. Ho avuto difficolta’ a trovare su internet un esempio, quindi ho deciso di scrivere un post con il mio approccio che fornisce metodi di estensione per IEnumerabe <T> per fare ricorsione:

Prima di tutto la mia struttura gerarchica:
Text | ID | Parent ID
A | 1 | –
B | 2 | –
C | 3 | 1
D | 4 | 1
E | 5 | 2

I dati sono rappresentati dall’oggetto

public class ObjectData
{
   public string Text { get; set; }
   public int Id { get; set; }
   public int ParentId { get; set; }
}

mentre i nodi gerarchici dal seguente oggetto:

public class NodeData
{
 public string Text { get; set; }
 public IEnumerable<NodeData> Children { get; set; }
}

Il nostro obiettivo e’ avere un oggetto gerarchico fatto in questo modo:
A –>
|_ C
|_ D
B —>
|_ E

Usando il mio metodo di estensione RecursiveJoin LINQ, è possibile trasformare i dati (rappresentati da ObjectData) in dati gerarchici (rappresentati da NodeData) come segue:

Prima di tutto creiamo i nostri dati:

ObjectData[] elements = new ObjectData[][]
{
   new ObjectData[]{Id = 1, Text = "A"},
   new ObjectData[]{Id = 2, Text = "B"},
   new ObjectData[]{Id = 3, ParentId = 1, Text = "C"},
   new ObjectData[]{Id = 4, ParentId = 1, Text = "D"},
   new ObjectData[]{Id = 5, ParentId = 2, Text = "E"}
};

E poi implementiamo il RecursiveJoin per creare il nostro oggetto “ricorsivo”

IEnumerable<NodeData> nodes = elements.RecursiveJoin(element => element.Id,
 element => element.ParentId,
 (ObjectData element, IEnumerable<NodeData> children) => new NodeData()
 {
 Text = element.Text,
 Children = children
 });

Ci saranno due root nodi A e B. A avra’ i figli C e D mentre B avra’ come figlio solo E.
L’esempio usa semplicemente la forma del metodo RecursiveJoin con la seguente firma:

public static IEnumerable<TResult> RecursiveJoin<TSource, TKey, TResult>
   (this IEnumerable<TSource> source,
      Func<TSource, TKey> parentKeySelector,
      Func<TSource, TKey> childKeySelector,
      Func<TSource, IEnumerable<TResult>, TResult> resultSelector);

Il codice della classe si puo’ trovare sul mio Github

Annunci

ExcelToLinq2Sql

Nel repository di google ho trovato questa libreria interessante per l’implementazione di excel in lin2sql. Il link è il seguente: http://code.google.com/p/linqtoexcel/wiki/UsingLinqToExcel.

Fatemi sapere… io ho iniziato a giocarci un poco….

Il modo più veloce di usare Excel in Linq2Sql

Di seguito alcune righe di codice per utilizzare dati di Excel in Linq2Sql :


string filename = @"C:\myfile.xls";
string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + filename + ";Extended Properties=Excel 8.0;";

OleDbDataAdapter dataAdapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", strConn);
DataSet myDataSet = new DataSet();
dataAdapter.Fill(myDataSet, "ExcelInfo");
DataTable dataTable = myDataSet.Tables["ExcelInfo"];

var query = from r in dataTable.AsEnumerable()
select new
{
RelationNr = r.Field<double>("RelationNumber"),
ClientName = r.Field<string>("ClientName"),
};

foreach (var item in query)
{
Console.WriteLine(item.ClientName);
}