public static void CombineSelectExpression(SchoolContext ctx)
        {
            Expression<Func<Course, CourseModel>> courseSelect =
                course => new CourseModel
                {
                    CourseId = course.CourseID,
                    Title = course.Title,
                    Credits = course.Credits
                };
            Expression<Func<Enrollment, EnrollmentBaseModel>> enrollmentSelect =
                enrollment => new EnrollmentBaseModel
                {
                    EnrollmentId = enrollment.EnrollmentID,
                    Grade = enrollment.Grade
                };
            Expression<Func<Student, StudentModel>> studentSelect =
                student => new StudentModel
                {
                    StudentId = student.ID,
                    FirstMidName = student.FirstMidName,
                    LastName = student.LastName
                };


            Expression<Func<Enrollment, CourseEnrollmentModel>> enrollmentWithStudentsSelect =
                enrollment => new CourseEnrollmentModel
                {
                };

            enrollmentWithStudentsSelect = enrollmentWithStudentsSelect.InheritInit(enrollmentSelect);

            enrollmentWithStudentsSelect = enrollmentWithStudentsSelect.AddMemberInit(
                enrollmentEntity => enrollmentEntity.Student,
                enrollmentModel => enrollmentModel.Student,
                studentSelect
                );

            enrollmentWithStudentsSelect = enrollmentWithStudentsSelect.AddMemberInit(
                enrollmentEntity => enrollmentEntity.Grade,
                enrollmentModel => enrollmentModel.GradeString,
                EnumExpressionExtensions.GetEnumToStringExpression<Grade?>(grade => grade.ToString())
                );

            Expression<Func<Course, CourseFullModel>> courseFullSelect =
                course => new CourseFullModel
                {
                };
            courseFullSelect = courseFullSelect.InheritInit(courseSelect);

            courseFullSelect = courseFullSelect.AddMemberInit(
                courseEntity => courseEntity.Enrollments,
                courseModel => courseModel.Enrollments,
                enrollmentWithStudentsSelect
                );

            var courses = ctx.Courses.Select(courseFullSelect).ToList();
        }
        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.SetData("DataDirectory", Path.GetFullPath("..\\..\\App_Data"));

            using (SchoolContext ctx = new SchoolContext())
            {
                HowWeDid(ctx);

                HowWeDo(ctx);

                PropertiesMapperExample(ctx);

                ExpressionsCombinationExample.CombineSelectExpression(ctx);
                SimpleSelect.ShowStudents(ctx);
                SelectNonCache.ShowStudents(ctx);
                InitInheritanceExample.ShowCourses(ctx);
                MemberInitExample.ShowStudents(ctx);
                CultureResolveExample.ShowCourses(ctx);
                FilterExpression.FilterStudents(ctx);
            }

            Console.ReadKey();
        }
        private static void HowWeDid(SchoolContext ctx)
        {
            var students = ctx.Students.Select(s => new StudentModel
            {
                StudentId = s.ID,
                FirstMidName = s.FirstMidName,
                LastName = s.LastName,
                EnrollmentDate = s.EnrollmentDate
            })
            .ToList();

            Console.WriteLine(GetResultsString("Students", students));

            //Reuse
            var studentsInOtherController = ctx.Students.Where(s => SqlFunctions.DateDiff("year", s.EnrollmentDate, DateTime.Now) < 12)
                .Select(s => new StudentModel
                {
                    StudentId = s.ID,
                    FirstMidName = s.FirstMidName,
                    LastName = s.LastName,
                    EnrollmentDate = s.EnrollmentDate
                })
                .ToList();
            Console.WriteLine(GetResultsString("Other Students", studentsInOtherController));

            Expression<Func<Enrollment, EnrollmentBaseModel>> enrollmentSelect = enrollment => new EnrollmentBaseModel
            {
                EnrollmentId = enrollment.EnrollmentID,
                Grade = enrollment.Grade
            };

            var enrollments1 = ctx.Enrollments.Select(enrollmentSelect).ToList();
            Console.WriteLine(GetResultsString("Enrollment1", enrollments1));

            var enrollments2 = ctx.Enrollments.Where(e => e.Grade != null).Select(enrollmentSelect).ToList();
            Console.WriteLine(GetResultsString("Enrollment2", enrollments2));

            var courses = ctx.Courses.Select(course => new CourseFullModel
            {
                CourseId = course.CourseID,
                Title = course.Title,
                Credits = course.Credits,
                Enrollments = course.Enrollments.Select(
                    enrollment => new CourseEnrollmentModel
                    {
                        EnrollmentId = enrollment.EnrollmentID,
                        Grade = enrollment.Grade,
                        GradeString = enrollment.Grade == null
                            ? null
                            : enrollment.Grade == Grade.A ? Grade.A.ToString()
                            : enrollment.Grade == Grade.B ? Grade.B.ToString()
                            : enrollment.Grade == Grade.C ? Grade.C.ToString()
                            : enrollment.Grade == Grade.D ? Grade.D.ToString()
                            : enrollment.Grade == Grade.F ? Grade.F.ToString()
                            : null,

                        Student = new StudentModel
                        {
                            FirstMidName = enrollment.Student.FirstMidName,
                            LastName = enrollment.Student.LastName,
                            EnrollmentDate = enrollment.Student.EnrollmentDate,
                            StudentId = enrollment.Student.ID
                        }
                    })
            });
            Console.WriteLine(GetResultsString("Courses", courses));
        }
        private static void PropertiesMapperExample(SchoolContext ctx)
        {
            var enrollments = ctx.Enrollments.ToList();

            var enrollmentModel = Mapper.Map<Enrollment, EnrollmentModel>(enrollments[0]);
            Console.WriteLine(enrollmentModel);

            var enrollmentModels = enrollments.MapSelect<Enrollment, EnrollmentModel>().ToList();
            Console.WriteLine(GetResultsString("Enrollments", enrollmentModels));
        }
        private static void HowWeDo(SchoolContext ctx)
        {
            var students = ctx.Students.ResolveSelect<Student, StudentModel>().ToList();
            Console.WriteLine(GetResultsString("Students", students));

            var studentsInOtherController = ctx.Students.Where(s => SqlFunctions.DateDiff("year", s.EnrollmentDate, DateTime.Now) < 12)
                .ResolveSelectExternal<Student, StudentModel>();
            Console.WriteLine(GetResultsString("Other Students", studentsInOtherController));

            var enrollments1 = ctx.Enrollments.ResolveSelect<Enrollment, EnrollmentBaseModel>().ToList();
            Console.WriteLine(GetResultsString("Enrollment1", enrollments1));

            var enrollments2 = ctx.Enrollments.Where(e => e.Grade != null).ResolveSelectExternal<Enrollment, EnrollmentBaseModel>().ToList();
            Console.WriteLine(GetResultsString("Enrollment2", enrollments2));

            var courses = ctx.Courses.ResolveSelectExternal<Course, CourseFullModel>().ToList();
            Console.WriteLine(GetResultsString("Courses", courses));

            var courseWithStudents = ctx.Courses.ResolveSelectExternal<Course, CourseWithOldStudentsModel>().ToList();
            Console.WriteLine(GetResultsString("Courses with students", courseWithStudents));
        }