Norbertas Brazaitis Norbertas Brazaitis - 4 days ago 7
C# Question

Linq strongly typed nested list

Is it possible to achieve this with LINQ? I have a class which is filled from database. There is child and his parents info. Child name, surname, class info, contacts. Parents names, surnames, contacts. Child may have multiple parents.

public class KontaktiniaiDuomenysPartialViewModel
{
/// <summary>
/// Child ID
/// </summary>
public long AsmenysId { get; set; }
/// <summary>
/// Child name
/// </summary>
public string Vardas { get; set; }
/// <summary>
/// Child surname
/// </summary>
public string Pavarde { get; set; }
/// <summary>
/// Child class ID
/// </summary>
public long KlasesId { get; set; }
/// <summary>
/// Child class name
/// </summary>
public string KlasesPavadinimas { get; set; }
/// <summary>
/// Child phone
/// </summary>
public string Telefonas { get; set; }
/// <summary>
/// Child mobile phone
/// </summary>
public string MobilusTelefonas { get; set; }
/// <summary>
/// Child email
/// </summary>
public string El_pastas { get; set; }
/// <summary>
/// Child Address
/// </summary>
public string Adresas { get; set; }
/// <summary>
/// Child father's/mother's id
/// </summary>
public long TevoAsmenysId { get; set; }
/// <summary>
/// Child father's/mother's address
/// </summary>
public string TevoAdresas { get; set; }
/// <summary>
/// Child father's/mother's name
/// </summary>
public string TevoVardas { get; set; }
/// <summary>
/// Child father's/mother's surname
/// </summary>
public string TevoPavarde { get; set; }
/// <summary>
/// Child father's/mother's email
/// </summary>
public string TevoElPastas { get; set; }
/// <summary>
/// Child father's/mother's phone
/// </summary>
public string TevoTelefonas { get; set; }
/// <summary>
/// Child father's/mother's phone
/// </summary>
public string TevoMobilusTelefonas { get; set; }

}


Example filling this class:

List<KontaktiniaiDuomenysPartialViewModel> data = new List<KontaktiniaiDuomenysPartialViewModel>();

KontaktiniaiDuomenysPartialViewModel data1 = new KontaktiniaiDuomenysPartialViewModel();

data1.AsmenysId = 1;
data1.Vardas = "Petras";
data1.Pavarde = "Petraitis";
data1.KlasesId = 2;
data1.KlasesPavadinimas = "k1";
data1.Telefonas = "860000000";
data1.MobilusTelefonas = "870000000";
data1.El_pastas = "asd@asd.lt";
data1.Adresas = "balt23";
// Petras mother info
data1.TevoAsmenysId = 3;
data1.TevoVardas = "Dalia";
data1.TevoPavarde = "zuk";
data1.TevoElPastas = "vejo@gmail.com";
data1.TevoTelefonas = "861111111";
data1.TevoMobilusTelefonas = "862222222";
data1.TevoAdresas = "Kaunas";

KontaktiniaiDuomenysPartialViewModel data2 = new KontaktiniaiDuomenysPartialViewModel();

data2.AsmenysId = 1;
data2.Vardas = "Petras";
data2.Pavarde = "Petraitis";
data2.KlasesId = 2;
data2.KlasesPavadinimas = "k1";
data2.Telefonas = "860000000";
data2.MobilusTelefonas = "870000000";
data2.El_pastas = "asd@asd.lt";
data2.Adresas = "balt23";
// Petras father info
data2.TevoAsmenysId = 4;
data2.TevoVardas = "juoz";
data2.TevoPavarde = "luk";
data2.TevoElPastas = "juoz@gmail.com";
data2.TevoTelefonas = "863333333";
data2.TevoMobilusTelefonas = "864444444";
data2.TevoAdresas = "Vilnius";

KontaktiniaiDuomenysPartialViewModel data3 = new KontaktiniaiDuomenysPartialViewModel();
data3.AsmenysId = 2;
data3.Vardas = "Eivis";
data3.Pavarde = "Konc";
data3.KlasesId = 5;
data3.KlasesPavadinimas = "k5";
data3.MobilusTelefonas = "880000000";
data3.Telefonas = "865555555";
data3.El_pastas = "Eivis@asd.lt";
data3.Adresas = "balt28";
// Eivis father info
data3.TevoAsmenysId = 5;
data3.TevoVardas = "obb";
data3.TevoPavarde = "tre";
data3.TevoElPastas = "obb@gmail.com";
data3.TevoTelefonas = "866666666";
data3.TevoMobilusTelefonas = "867777777";
data3.TevoAdresas = "KLP";

data.Add(data1);
data.Add(data2);
data.Add(data3);


I want to group data into this class:

public class KontaktiniaiDuomenysPartialViewModelGrouped
{
/// <summary>
/// Child id
/// </summary>
public long AsmenysId { get; set; }
/// <summary>
/// Child name
/// </summary>
public string Vardas { get; set; }
/// <summary>
/// Child surname
/// </summary>
public string Pavarde { get; set; }
/// <summary>
/// Child class
/// </summary>
public KlaseModels Klase { get; set; }
/// <summary>
/// Child father's/mother's info
/// </summary>
public IList<TevoKontaktai> Tevaii { get; set; }
/// <summary>
/// Child contacts
/// </summary>
public KontaktiniaiDuomenysModel Kontaktai { get; set; }
}


Extra classes:

public class KlaseModels
{
/// <summary>
/// child class id
/// </summary>
public long Id { set; get; }
/// <summary>
/// Child class name
/// </summary>
public string Pavadinimas { set; get; }
}
public class TevoKontaktai
{
/// <summary>
/// Child father's/mother's id
/// </summary>
public long AsmenysId { get; set; }
/// <summary>
/// Child father's/mother's name
/// </summary>
public string Vardas { get; set; }
/// <summary>
/// Child father's/mother's surname
/// </summary>
public string Pavarde { get; set; }
/// <summary>
/// Child father's/mother's contacts
/// </summary>
public KontaktiniaiDuomenysModel Kontaktai { get; set; }
}

public class KontaktiniaiDuomenysModel
{
/// <summary>
/// Child father's/mother's email
/// </summary>
public string ElPastas { get; set; }
/// <summary>
/// Child father's/mother's phone
/// </summary>

public string Telefonas { get; set; }
/// <summary>
/// Child father's/mother's mobile phone
/// </summary>

public string MobilusTelefonas { get; set; }
/// <summary>
/// Child father's/mother's address
/// </summary>
public string Adresas { get; set; }
}


Expected result:

IList<KontaktiniaiDuomenysPartialViewModelGrouped> afterLinq

afterLinq[0]

afterLinq[0].AsmenysId = 1
afterLinq[0].Vardas = "Petras"
afterLinq[0].Pavarde = "Petraitis"

afterLinq[0].Klase.Id = 2
afterLinq[0].Klase.Pavadinimas = "k1"
afterLinq[0].Kontaktai.ElPastas = "asd@asd.lt"
afterLinq[0].Kontaktai.Telefonas = "860000000"
afterLinq[0].Kontaktai.MobilusTelefonas = "870000000"
afterLinq[0].Kontaktai.Adresas = "balt23"

afterLinq[0].Tevaii[0].AsmenysId = 3
afterLinq[0].Tevaii[0].Vardas = "Dalia"
afterLinq[0].Tevaii[0].Pavarde = "zuk"
afterLinq[0].Tevaii[0].Kontaktai.ElPastas = "vejo@gmail.com"
afterLinq[0].Tevaii[0].Kontaktai.Telefonas = "861111111"
afterLinq[0].Tevaii[0].Kontaktai.MobilusTelefonas = "862222222"
afterLinq[0].Tevaii[0].Kontaktai.Adresas = "Kaunas";

afterLinq[0].Tevaii[1].AsmenysId = 4
afterLinq[0].Tevaii[1].Vardas = "juoz"
afterLinq[0].Tevaii[1].Pavarde = "luk"
afterLinq[0].Tevaii[1].Kontaktai.ElPastas = "juoz@gmail.com"
afterLinq[0].Tevaii[1].Kontaktai.Telefonas = "863333333"
afterLinq[0].Tevaii[1].Kontaktai.MobilusTelefonas = "864444444"
afterLinq[0].Tevaii[1].Kontaktai.Adresas = "Vilnius";







afterLinq[1]

afterLinq[1].AsmenysId = 2
afterLinq[1].Vardas = "Eivis"
afterLinq[1].Pavarde = "Konc"

afterLinq[1].Klase.Id = 5
afterLinq[1].Klase.Pavadinimas = "k5"


afterLinq[1].Kontaktai.ElPastas = "Eivis@asd.lt"
afterLinq[1].Kontaktai.Telefonas = "865555555"
afterLinq[1].Kontaktai.MobilusTelefonas = "880000000"
afterLinq[1].Kontaktai.Adresas = "balt28"

afterLinq[1].Tevaii[0].AsmenysId = 5
afterLinq[1].Tevaii[0].Vardas = "obb"
afterLinq[1].Tevaii[0].Pavarde = "tre"
afterLinq[1].Tevaii[0].Kontaktai.ElPastas = "obb@gmail.com"
afterLinq[1].Tevaii[0].Kontaktai.Telefonas = "866666666"
afterLinq[1].Tevaii[0].Kontaktai.MobilusTelefonas = "867777777"
afterLinq[1].Tevaii[0].Kontaktai.Adresas = "KLP";

Answer
        var grouped = new[] { data1, data2, data3 }
            .GroupBy(kd => new
            {
                kd.AsmenysId,
                kd.Vardas,
                kd.Pavarde,
                kd.KlasesId,
                kd.KlasesPavadinimas,
                kd.El_pastas,
                kd.Telefonas,
                kd.MobilusTelefonas,
                kd.Adresas
            })
            .Select(g => new KontaktiniaiDuomenysPartialViewModelGrouped
            {
                AsmenysId = g.Key.AsmenysId,
                Vardas = g.Key.Vardas,
                Pavarde = g.Key.Pavarde,
                Klase = new KlaseModels
                {
                    Id = g.Key.KlasesId,
                    Pavadinimas = g.Key.KlasesPavadinimas
                },
                Kontaktai = new KontaktiniaiDuomenysModel
                {
                    ElPastas = g.Key.El_pastas,
                    Telefonas = g.Key.Telefonas,
                    MobilusTelefonas = g.Key.MobilusTelefonas,
                    Adresas = g.Key.Adresas
                },
                Tevaii = g.Select(kd => new TevoKontaktai { 
                    AsmenysId = kd.TevoAsmenysId,
                     Vardas = kd.TevoVardas,
                     Pavarde = kd.TevoPavarde,
                    Kontaktai = new KontaktiniaiDuomenysModel
                    {
                        ElPastas = kd.TevoElPastas,
                        Telefonas = kd.TevoTelefonas,
                        MobilusTelefonas = kd.TevoMobilusTelefonas,
                        Adresas = kd.TevoAdresas
                    }
                }).ToList()
            });

Btw, I guess relational data tables could be the reason of your flatten models but in fact you can load hierarchical model using some techniques like XML or you may try with NoSQL DB. :D

Comments