Reusable Calculations For LINQ Projections In Entity Framework (Code First)

后端 未结 2 996
走了就别回头了
走了就别回头了 2020-12-10 17:20

My domain model has a lot of complex financial data that is the result of fairly complex calculations on multiple properties of various entities. I generally include these

2条回答
  •  暖寄归人
    2020-12-10 17:36

    You can encapsulate logic by creating a class that contains the original Entity and the additional calculated property. You then create helper methods that project to the class.

    For example, if we were trying to calculate the tax for an Employee and a Contractor entity, we could do this:


    //This is our container for our original entity and the calculated field
    public class PersonAndTax 
    {
        public T Entity { get; set; }
        public double Tax { get; set; }
    }
    

    public class PersonAndTaxHelper
    {
        // This is our middle translation class
        // Each Entity will use a different way to calculate income
        private class PersonAndIncome
        {
            public T Entity { get; set; }
            public int Income { get; set; }
        }
    

    Income calculating methods

        public static IQueryable> GetEmployeeAndTax(IQueryable employees)
        {
            var query = from x in employees
                        select new PersonAndIncome
                        {
                            Entity = x,
                            Income = x.YearlySalary
                        };
            return CalcualateTax(query);
        }
    
        public static IQueryable> GetContratorAndTax(IQueryable contractors)
        {
            var query = from x in contractors
                        select new PersonAndIncome
                        {
                            Entity = x,
                            Income = x.Contracts.Sum(y => y.Total) 
                        };
    
            return CalcualateTax(query);
        }
    

    Tax calculation is defined in one place

        private static IQueryable> CalcualateTax(IQueryable> personAndIncomeQuery)
        {
            var query = from x in personAndIncomeQuery
                        select new PersonAndTax
                        {
                            Entity = x.Entity,
                            Tax = x.Income * 0.3
                        };
            return query;
        }
    }
    

    Our view model projections using the Tax property

        var contractorViewModel = from x in PersonAndTaxHelper.GetContratorAndTax(context.Contractors)
                                select new
                                {
                                    x.Entity.Name,
                                    x.Entity.BusinessName
                                    x.Tax,
                                };
    
        var employeeViewModel = from x in PersonAndTaxHelper.GetEmployeeAndTax(context.Employees)
                                select new
                                {
                                    x.Entity.Name,
                                    x.Entity.YearsOfService
                                    x.Tax,
                                };
    

提交回复
热议问题