DEV Community

Cover image for I used my first ever Expression<Func<TInput, TOutput>> today to create reusable LINQ Queries
Grant Hair
Grant Hair

Posted on

I used my first ever Expression<Func<TInput, TOutput>> today to create reusable LINQ Queries

Up to this point in my career I have yet to reuse a Select lambda in my LINQ queries, today that changed.

I was messing around with something for a technical session within my team when I noticed I had the exact same code for 2 Select functions.

Basically I wanted to Select my DB entity type to a Domain Transfer Object type. I could've done this through some mapping or whatever but I chose this way to show off the barebones of what I was trying to show and tell at our tech session.

My code looks like this, I have a VERY basic API (that uses probably 0 best practices) that returns various information about Golf courses, scores, handicaps etc etc.

Side note, I love golf, its a great excuse to get outdoors which is probably going against the grain in a Covid fuelled world but anyways I'll keep going.

Golf Stuff

I managed to take a pretty sick photo of a tree whilst golfing at the weekend.

Tree

Where was I... ah yes the codes.


public class CourseDataIntegrationServices : ICourseDataIntegrationServices
    {
        private readonly GolfScoresDbContext _context;

        public CourseDataIntegrationServices(GolfScoresDbContext context)
        {
            _context = context;
        }

        public List<CourseDto> GetAllCourses()
        {
            return _context
                .Courses
                .Include(x => x.Holes)
                .Select(_selectCourseToCourseDto)
                .ToList();
        }

        public CourseDto GetCourseById(Guid id)
        {
            return _context
                .Courses
                .Include(x => x.Holes)
                .Select(_selectCourseToCourseDto)
                .FirstOrDefault(x => x.Id == id);
        }

        private readonly Expression<Func<Course, CourseDto>> _selectCourseToCourseDto = (x) =>
            new CourseDto
            {
                Holes = x.Holes.Select(h => new HolesDto
                {
                    Name = h.Name,
                    HandicapIndex = h.HandicapIndex,
                    Par = h.Par,
                    Id = h.Id,
                    Number = h.Number,
                    Yardage = h.Yardage
                }).OrderBy(h => h.Number).ToList(),
                Id = x.Id,
                Name = x.Name,
                Par = x.Par
            };
    }

Enter fullscreen mode Exit fullscreen mode

The nice thing about this is that I know have a reusable way of mapping my DB entity to my DTO without the need of a 3rd part NuGet package and tbh the code is pretty plain vanilla in terms of added sprinkles.

Expression<Func<Course, CourseDto>> in your head can become
Expression<Func<MyInputType, MyOutputType>>

I can take the above one step further by writing a second Expression> for my Hole selection...don't be nasty.

I think I will leave that for another day.

Anyways I hope this has been of some help to those looking to create reusable select criteria for LINQ queries.

Ciao for now

Top comments (0)