Модель Entity Framework Core с абстрактным классом - PullRequest
0 голосов
/ 06 января 2019

У меня есть вопрос

Я создаю базу данных Code First в ASP .NET Core 2.1 и Entity Framework 2.1.1. Сейчас я на этапе планирования, и у меня есть один вопрос. Я хочу иметь список экземпляров класса абстрактного работника с методом, который будет работать по-разному. Мой код:

У меня есть Farm:

public class Farm
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }

        public virtual List<Farmer> Farmers { get; set; } //my problem
        public virtual List<Driver> Drivers { get; set; } //starts here!
    }

В ферме у меня есть рабочие. Я сделал abstract class для этого:

public abstract class Worker
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("Farm")]
    public int FarmId { get; set; }
    public Farm Farm { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public float UsdPerHour { get; set; }
    public int HoursPerDay { get; set; }
    public int DaysOfWork { get; set; }

    public abstract float CountSalary();
}

Рабочий может быть Driver или Farmer:

public class Farmer : Worker
{
    public float UsdPerHour = 9;
    public int HoursPerDay = 8;
    public int DaysOfWork = 20; 
    // CountSalary() here, but in diffrent way!
}

public class Driver : Worker
{
    public float UsdPerHour = 10;
    public int HoursPerDay = 7;
    public int DaysOfWork = 18;
    // CountSalary() here, but in diffrent way!
}

И мой FarmDbContext:

public class FarmDbContext : DbContext
{
    public FarmDbContext(DbContextOptions<FarmDbContext> options) : base(options) { }

    public DbSet<Farm> Farms { get; set; }
    //public DbSet<Worker> Workers { get; set; }
    public DbSet<Farmer> Farmers { get; set; } // What to do here?
    public DbSet<Driver> Drivers { get; set; } // Let Farmers and Drivers
                                               // Or Workers?
}

В Моем farm у меня есть два вида работников. Для каждой «Позиции» я хочу рассчитывать зарплату по-разному.

Что я хочу сделать в коде:

var Workers = List<Worker>
Workers.Add(New Driver());
Workers.Add(new Farmer()): 

foreach(object o in Workers)
   int salary = o.CountSalary()

// i know that code is wrong, but i describe the way that i want to achive my goal

Не могли бы вы объяснить мне, как спланировать мое DbContext, чтобы достичь, чего я хочу? Farmer и Driver должны иметь жестко закодированные значения свойств. Когда я допускаю DbContext, как указано выше, в моем коде, я получаю две таблицы, dbo.Drivers и dbo.Farmers. Если это будет работать так, как я объяснил выше? Возможно ли в EF блокировать это жестко закодированное значение в базе данных и иметь его в каждой записи таблиц данных i?

1 Ответ

0 голосов
/ 08 января 2019

Ваши классы Farmer и Driver не имеют новых свойств, только некоторые константы для вычислений. Это не проблема уровня Модель / База данных, а работа уровня Сервиса.

Мое предложение:

public enum WorkerType
{
  Farmer,
  Driver
}

Рабочий класс:

public class Worker
{
  [Key]
  public int Id { get; set; }

  [ForeignKey("Farm")]
  public int FarmId { get; set; }
  public Farm Farm { get; set; }

  public string FirstName { get; set; }
  public string LastName { get; set; }
  public WorkerType WorkerType {get; set; } // assuming a worker can only be a Farmer or a Driver
}

DbContext:

public class FarmDbContext : DbContext
{
    public FarmDbContext(DbContextOptions<FarmDbContext> options) : base(options) { }

    public DbSet<Farm> Farms { get; set; }
    public DbSet<Worker> Workers { get; set; }
}

И тогда у вас может быть метод обслуживания или продления, который рассчитывает заработную плату, например:

public static class WorkerExtensions
{
  public static float Salary(this Worker worker)
  {
    switch(worker.WorkerType)
    {
      case WorkerType.Farmer:
        //calculate and return

      case WorkerType.Driver:
        //calculate and return

      default:
        return -1;
    }
  }
}

Теперь вы можете получать зарплату рабочим:

foreach(var worker in Workers)
   var salary = worker.Salary();

Проблема здесь в том, что каждый раз, когда изменяются ваши расчетные константы, вам нужно менять код и перестраивать / переиздавать. Для этого вы можете создать таблицу информации о заработной плате в своей базе данных и получать эту информацию оттуда, а также изменять ее в любое время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...