从数据库加载数据到以下结构的最佳方法是什么?

时间:2016-01-18 16:37:20

标签: c# design-patterns

数据库架构如下

员工

  • EmployeeID(int,pk)
  • 姓(nvarchar的)
  • 名字(nvarchar的)
  • 电子邮件(nvarchar的)
  • EmployeeType(int)的
  • 薪水(十进制)
  • HourlyRate(十进制)

优势

  • BenefitID(int,pk)
  • 福利(nvarchar)
  • EmployeeID(int,fk)

员工表包含所有员工数据。薪资字段适用于全职员工,小时费率适用于每小时员工。优惠仅适用于全职员工。

我已经设置了一个将返回所有员工的服务类。 我还想初始化Salaried Employee对象的所有好处。我使用switch语句设置了employee类型的检查,然后创建对象的实例并将其添加到集合中。

这将完美地运作。

我遇到的问题是每次添加新类型的员工时,我都必须修改Employee服务并为switch语句添加逻辑以处理新类型的员工。这违反了开放式原则。

我的问题是在这种情况下,将数据从数据库加载到对象的最佳方法是什么?

public enum EmployeeType
{
    FullTime =1,
    PartTime =2
}

public class EmployeeBenefit
{
    private string _benefit;
    private Employee _employee;

    public int EmployeeId { get { return Employee.Id; } }
    public Employee Employee { get { return _employee; } }
    public string Benefit { get { return _benefit; } }

    public EmployeeBenefit(Employee emp, string benefit)
    {
        _benefit = benefit;
        _employee = emp;
    }
}

public abstract class Employee
{
    public int Id { get; set; }
    public abstract EmployeeType Type { get; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
}

public class SalariedEmployee: Employee
{
    private ICollection<EmployeeBenefit> _benefits;

    public SalariedEmployee()
    {
        _benefits = new List<EmployeeBenefit>();
    }

    public IEnumerable<EmployeeBenefit> Benefits { get {return _benefits;} }
    public double Salary { get; set; }

    public override EmployeeType Type
    {
        get { return EmployeeType.FullTime; }
    }

    public void AddBenefit(string benefit)
    {
        EmployeeBenefit ebenefit = new EmployeeBenefit(this, benefit);

        if (Benefits.Contains(ebenefit))
            _benefits.Add(ebenefit);
    }

    public void RemoveBenefit(string benefit)
    {
        EmployeeBenefit ebenefit = new EmployeeBenefit(this, benefit);

        if(_benefits.Contains(ebenefit))
            _benefits.Remove(ebenefit);
    }
}

public class PartTimeEmployee : Employee
{
    public override EmployeeType Type
    {
        get { return EmployeeType.PartTime; }
    }

    public double HourlyRate { get; set; }
}

public class EmployeeService
{
    public IEnumerable<Employee> GetAll() {         
        List<Employee> _lst = new List<Employee>();

        using(var db = new EmployeeContext)
        {

            foreach(Employee e in db.Employees)
            {

                switch(e.Type){
                    case EmployeeType.PartTime:
                        PartTimeEmployee pt = new PartTimeEmployee();
                        //initialize the values of parttime employee like hourly rate

                        _lst.Add(pt);
                        break;
                    case EmployeeType.FullTime:
                        SalariedEmployee se = new SalariedEmployee();
                        //initialize the value of salaried employees like benefits, salary
                        _lst.Add(se);
                        break;
                }

            }


        }

        return _lst;
    }
}

1 个答案:

答案 0 :(得分:0)

您可以做的只是将员工类型保留为Employee类中的String属性,并将类型动态添加到Employee类。我没有在这里看到Employee Type类的实际需要。

如果您绝对需要这样的类,请将其声明为类而不是枚举,并且具有字符串属性,该属性将是该类型的名称。在此之后,您将从查询中获取每种新类型,初始化new EmployeeType()并使用setter添加该字符串。然后将EmployeeType设置为Employee类。

根据我的说法,这是一个更好的设计,因为你不需要在枚举中硬编码字符串值。

为了好处,你可以做的是为具体的Employee类提供一个好处属性(或者将其命名为其他东西,因为你已经有了一个抽象的Employee)。只有在员工类型受薪时才设置价值。我就是这样做的。