c# - Use linq to map parent child structure -


i have domain classes separated ones use in views, when retrieving data have map domain classes view ones. until have been straight forward, have case in need map parent-child classes domain parent-child classes on view.

using foreach structures works fine, have quite few linq methods mapping between domain , view classes, need refactored accomodated new requirements , faster if knew how linq. in advance.

as example of i'm trying accomplish see code below:

in repository have classes:

    public class parent {     public int parentid { get; set; }     public string parentname { get; set; } };  public class childa : parent {     public string childpropertya { get; set; } };  public class childb : parent {     public string childpropertyb { get; set; } }; 

then in ui have classes:

    public class parentvm {     public int parentidvm { get; set; }     public string parentnamevm { get; set; } };  public class childavm : parentvm {     public string childpropertyavm { get; set; } };  public class childbvm : parentvm {     public string childpropertybvm { get; set; } }; 

now have service class in methods 1 below:

        public getparentvms()     {         var parents = initializerepositoryclass();          var parentsvm = maprepositorytoviewclasses(parents);          showresult(parentsvm);     } 

where:

        public list<parent> initializerepositoryclass()     {         var parents = new list<parent>(){             new childa(){parentid=1, parentname="parent 1", childpropertya="a"},             new parent(){parentid=2, parentname="parent 2"},             new childb(){parentid=3, parentname="parent 3", childpropertyb="b"},         };         return parents;     }     private list<parentvm> maprepositorytoviewclasses(list<parent> parents)     {         var parentsvm = new list<parentvm>();         foreach (var item in parents)         {             if (item childa)             {                 var itemvm = item childa;                 parentsvm.add(                     new childavm() { parentidvm = itemvm.parentid, parentnamevm = itemvm.parentname, childpropertyavm = itemvm.childpropertya }                 );             }             else if (item childb)             {                 var itemvm = item childb;                 parentsvm.add(                 new childbvm() { parentidvm = itemvm.parentid, parentnamevm = itemvm.parentname, childpropertybvm = itemvm.childpropertyb }                 );             }             else             {                 var itemvm = item parent;                 parentsvm.add(                 new parentvm() { parentidvm = itemvm.parentid, parentnamevm = itemvm.parentname }                 );             }         }         return parentsvm;     }     private void showresult(list<parentvm> parentsvm)     {         foreach (var item in parentsvm)         {             if (item childavm)             {                 var ca = (childavm)item;                 console.writeline("child " + ca.childpropertyavm);             }             else if (item childbvm)             {                 var cb = (childbvm)item;                 console.writeline("child b " + cb.childpropertybvm);             }             else             {                 console.writeline("parent ");             }         }     } 

the code above work, change method maprepositorytoviewclasses uses linq, , looks 1 below:

        private list<parentvm> maprepositorytoviewclasseslinq(list<parent> parents)     {         var parentsvm =             p in parents                  case                     p childa select new childavm() {childpropertyavm = p.childpropertya, ...};                 else                     p childb select new childbvm() {childpropertybvm = p.childpropertyb, ...};                 else                     select new parentvm() {parentidvm = p.parentid};       return parentsvm.tolist();     } 

any ideas? thanks.

you need changes in code make better

1) have introduce factory create vm's instances.

class vmfactory {     public parentvm create(parent obj)     {         var childa = obj childa;         if (childa != null)         {             return new childavm() { parentidvm = childa.parentid, parentnamevm = childa.parentname, childpropertyavm = childa .childpropertya };         }          var childb = obj childb;         if(childb != null)         {                 return new childbvm() { parentidvm = childb.parentid, parentnamevm = childb.parentname, childpropertybvm = childb.childpropertyb };         }          return new parentvm() { parentidvm = obj.parentid, parentnamevm = obj.parentname };     } } 

2) can simplify code @ maprepositorytoviewclasses method

private list<parentvm> maprepositorytoviewclasses(list<parent> parents) {     // factory instance can provided outer scope     var factory = new vmfactory();     var parentsvm = new list<parentvm>();     foreach (var item in parents)     {         parentsvm.add(factory.create(item));     }      return parentsvm; } 

3) final step, let's use linq map

private list<parentvm> maprepositorytoviewclasses(list<parent> parents) {     // factory instance can provided outer scope     var factory = new vmfactory();      return parents.select(factory.create).tolist(); } 

it's done


yet attempt solve it

1) create extensions solve common tasks.

static class ext {     public static parentvm map<tin>(this tin obj, func<tin, parentvm> func)         tin : parent     {         var source = obj tin;         return source != null             ? func(obj)             : null;     } } 

2) use extension method vms

private list<parentvm> maprepositorytoviewclasseslinq(list<parent> parents) {     var tmp = p in parents               select                   p.map<childa>(c => new childavm() { parentidvm = c.parentid, parentnamevm = c.parentname, childpropertyavm = c.childpropertya }) ??                   p.map<childb>(c => new childbvm() { parentidvm = c.parentid, parentnamevm = c.parentname, childpropertybvm = c.childpropertyb }) ??                   new parentvm() { parentidvm = obj.parentid, parentnamevm = obj.parentname };      return tmp.tolist(); } 

Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - .htaccess mod_rewrite for dynamic url which has domain names -

Website Login Issue developed in magento -