<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ryan English</title>
    <description>The latest articles on DEV Community by Ryan English (@grizzlyenglish).</description>
    <link>https://dev.to/grizzlyenglish</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F653357%2Fe534df75-1db1-4feb-8c35-c32ae51c495b.jpeg</url>
      <title>DEV Community: Ryan English</title>
      <link>https://dev.to/grizzlyenglish</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/grizzlyenglish"/>
    <language>en</language>
    <item>
      <title>Using LINQ Expression Trees to build maintainable DTO modeling</title>
      <dc:creator>Ryan English</dc:creator>
      <pubDate>Fri, 02 Jul 2021 22:00:36 +0000</pubDate>
      <link>https://dev.to/grizzlyenglish/using-linq-expression-trees-to-build-maintainable-dto-modeling-366i</link>
      <guid>https://dev.to/grizzlyenglish/using-linq-expression-trees-to-build-maintainable-dto-modeling-366i</guid>
      <description>&lt;p&gt;Using LINQ Expression Trees to build maintainable DTO modeling&lt;br&gt;
One of the biggest problems I faced working on a medium sized .NET Framework code base was writing maintainable modeling systems without excessive code duplication.&lt;br&gt;
It becomes all too easy to utilize extension methods to model your DTOs from a given query's select, or to pull out too much data from your data set in order to instantiate a DTO. With expression tress you can minimize the data pulls as well as create simple mappings of the data.&lt;/p&gt;



&lt;p&gt;Let's say we have two classes in our dataset: &lt;em&gt;Student&lt;/em&gt; and &lt;em&gt;Class&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Student
{
    public int Id { get; set; }
    public string Name { set; set; }
    public virtual ICollection&amp;lt;Class&amp;gt; Classes { get; set; }
}

public class Class
{
    public int Id { get; set; }
    public string Name { set; set; }
    public virtual ICollection&amp;lt;Class&amp;gt; Students { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we have two DTOs: &lt;em&gt;StudentModel&lt;/em&gt; and &lt;em&gt;ClassModel&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class StudentModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class ClassModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List&amp;lt;StudentModel&amp;gt; Students { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are already two obvious errors you can make here: having code duplication generate the &lt;em&gt;StudentModel&lt;/em&gt; depending on the entry point of the code, or having to pull all the properties out of the database (in this case not a big deal) in order to model your DTOs in memory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Utilizing LINQ to Entities you can see 
*  how we have to specify StudentModels mappings 
*  in the class models select statement
*/ 
return database.Classes
    .Select(cl =&amp;gt; new ClassModel
    {
        Id = cl.Id
        Students = cl.Students.Select(st =&amp;gt; new StudentModel
        {
            Id = st.Id
        }
    })
    .ToList()

// Or we could pull all the data in order to get a cleaner modeling
return database.Classes
    .ToList()
    .Select(cl =&amp;gt; new ClassModel(cl))
    .ToList()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you can generate expression trees to handle the modeling, which allows you to focus on specifying the binding between the data and the property. This is exactly how the first &lt;em&gt;Select&lt;/em&gt; above operates, the difference is we can build the trees in order to reuse pieces throughout the system.&lt;/p&gt;

&lt;p&gt;So let's take that same &lt;em&gt;ClassModel&lt;/em&gt; and generate its expression tree like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ClassModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List&amp;lt;StudentModel&amp;gt; Students { get; set; }

    /* 
     * Here we define how a the source of 
     * the object is bound to this object
     * The passed in expression is the parameter of 
     * select statement, in this case will be the type of Class
     */
    public static MemberAssignment[] Assignments(Expression param)
    {
        return new MemberAssignment[]
        {
           /* 
            * Here we are saying we want to bind the property Id on 
            * ClassModel to the property Id 
            * on the passed param (Class)
            */
            Expression
                .Bind(
                    typeof(ClassModel).GetProperty("Id"), 
                    Expression.Property(param, "Id")
                ),
                // Same for name as above            
                        Expression
                .Bind(
                    typeof(ClassModel).GetProperty("Name"), 
                    Expression.Property(param, "Name")
                ),
            /* 
            * Here it gets a bit tricker, we are still binding 
            * students to students but we need to get a list 
            * (See StudentModel)
            */
            Expression
                 .Bind(
                    typeof(ClassModel).GetProperty("Students"), 
                    StudenModel.InitList(
                        Expression.Property(param, "Students")
                    )
                 )
        };
    }

    /*
     * Here is how the ClassModel is "newed" it creates 
     * a new ClassModel with a parameterless constructor
     * and binds all the known bindings to body, generating
     * new ClassModel { // Insert Bindings }
     */
    public static Expression&amp;lt;Func&amp;lt;Class, ClassModel&amp;gt;&amp;gt; Init()
    {
        // Define the soruce of the expressions type
        // in this case class dbo
        ParameterExpression param = 
                  Expression.Parameter(typeof(Class), "source");
        // New the class model using the above bindings
        MemberInitExpression init = 
             Expression.MemberInit(
                Expression.New(typeof(ClassModel)), 
                Assignments(param)
             );
        // Return the lambda which is 
        // source =&amp;gt; new ClassModel { Id = source.Id, Name = source.Name }
        return Expression.Lambda&amp;lt;Func&amp;lt;Class, ClassModel&amp;gt;&amp;gt;(init, param);
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, we can create reusable expression trees to model &lt;em&gt;ClassModel&lt;/em&gt; no matter the data source, by specifying how a &lt;em&gt;Class&lt;/em&gt; object binds to a &lt;em&gt;ClassModel&lt;/em&gt; object - as long as we have a mapping. This becomes pretty apparent when we look at the &lt;em&gt;StudentModel&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class StudentModel
{
    public int Id { get; set; }
    public string Name { get; set; }

    // Same as the class model define the assignments
    public static MemberAssignment[] Assignments(Expression param)
    {
        return new MemberAssignment[]
        {
            /*
            * Here we are saying we want to bind the property Id 
            * on StudentModel to the property Id 
            * on the passed param (Student)
            */
            Expression.Bind(
                     typeof(StudentModel).GetProperty("Id"), 
                     Expression.Property(param, "Id")
            ),
            // Same for name as above
            Expression.Bind(
                     typeof(StudentModel).GetProperty("Name"), 
                     Expression.Property(param, "Name")
            ),
        };
    }

   // Just init a single StudentModel
   public static Expression&amp;lt;Func&amp;lt;Student, StudentModel&amp;gt;&amp;gt; Init()
   {
     ParameterExpression param = 
           Expression.Parameter(typeof(Student), "source");
     MemberInitExpression init = 
           Expression.MemberInit(
               Expression.New(typeof(StudentModel)), 
               Assignments(param)
           );
     return Expression.Lambda&amp;lt;Func&amp;lt;Student, StudentModel&amp;gt;&amp;gt;(init, param);
   }

    /*
     * This is a bit out of the scope of the article, 
     * but I wanted to include it to show the capablities  
     * Basically here we are generating the sub tree 
     * that will select and to list all the students in the class
     */
    public static MethodCallExpression InitList(Expression param)
    {
        /*
        * Just like the member init we have to bind 
        * the source of the select statement 
        * to the type of Student
        */
        ParameterExpression studentParam = 
           Expression.Parameter(typeof(Student), "source");

        /*
        * Next we new a student model with the assigments from above
        * So now we have 
        * new StudentModel{ Id = source.Id, Name = soruce.Name }
        */
        MemberInitExpression studentModelInit = 
           Expression.MemberInit(
               Expression.New(typeof(StudentModel)), 
               Assignments(studentParam)
           );

        /*
        * And finally smack these two together in a 
        * lambda statement to generate
        * source =&amp;gt; 
        * new StudentModel{ Id = source.Id, Name = soruce.Name }
        */
        LambdaExpression lambda = 
           Expression.Lambda&amp;lt;Func&amp;lt;Student, StudentModel&amp;gt;&amp;gt; 
                (studentModelInit, studentParam);

        /*
        * Now we have to specify we are making a call 
        * to the select statement and specify the types
        */
        MethodCallExpression studentSelect = Expression.Call(
            null,
            GetSelect().MakeGenericMethod(new Type[] { 
                // Our select "in"
                typeof(Student), 
                // Our select "out"
                typeof(StudentModel) 
                }),
            new Expression[] { 
                // The binding param (a list of students)
                param, 
                // The lamda body from above
                lambda 
                });

        // And finally to list it to get all of them
        return Expression.Call(
            typeof(Enumerable),
            "ToList",
            // Same here define the type of the out
            new Type[] { typeof(StudentModel) },
            // The "body" of the to list
            studentSelect
            );
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have all the bindings defined, we can make queries as so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return database.Classes
    .Select(ClassModel.Init())
    .ToList();

return database.Students
    .Select(StudentModel.Init())
    .ToList()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;You might be thinking, "Wow, that is a lot of extra code and overhead in order to generate models" and I thought the same thing, which is why I created &lt;a href="https://github.com/GrizzlyEnglish/modelLINQ"&gt;modelLINQ&lt;/a&gt; (there are alternatives like &lt;a href="https://automapper.org/"&gt;AutoMapper&lt;/a&gt;).&lt;br&gt;
Using modelLINQ you can write smaller easier-to-digest modeling systems in order to create maintainable code. For example, I swapped the above code using modelLINQ.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class StudentModel
{
    public int Id { get; set; }
    public string Name { get; set; }

   /*
    * All we need to do is setup the init function
    * I like to use From&amp;lt;Source&amp;gt; syntax
    */
    public static Func&amp;lt;Expression, MemberAssignments[]&amp;gt; FromStudent() 
     param =&amp;gt;
        new MemberAssigment[] {
            // Directly bind from source to result on both properties
            param.DirectBind&amp;lt;StudentModel&amp;gt;("Id"),
            param.DirectBind&amp;lt;StudentModel&amp;gt;("Name")
        };
}

public class ClassModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List&amp;lt;StudentModel&amp;gt; Students { get; set; }

    public static Func&amp;lt;Expression, MemberAssignments[]&amp;gt; FromClass() 
        param =&amp;gt;
        new MemberAssigment[] {
            // Directly bind from source to result on both properties
            param.DirectBind&amp;lt;StudentModel&amp;gt;("Id"),
            param.DirectBind&amp;lt;StudentModel&amp;gt;("Name"),

            /*
            * Creates a list of StudentModels
            * We have to specify the binding model, the source, 
            * and the result in order to generate the list mapping
            */
            param.BindSelectedList&amp;lt;ClassModel, Class, StudentModel&amp;gt;
                ("Students", "Students", StudentModel.FromStudent)
        };
}

// How to query
database.Class
  .Select(ClassModel.FromClass.Model&amp;lt;Class, ClassModel&amp;gt;())
  .ToList()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks for reading; I hope someone finds it useful! If you have any thoughts, or believe I am wrong, please comment I'd love to hear your feedback!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
