Reputation: 5228
I have a question
I make a Code First Database In ASP .NET Core 2.1
and Entity Framework 2.1.1
. For now, im in a planning step and i have one question. I want to have a list of instance of abstract worker's class with method, that will work difrently. My code:
I have a 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!
}
In Farm instance i have Workers. I made an abstract class
for it:
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();
}
Worker can be a Driver
or a 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!
}
And my 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?
}
In My farm
i have two kinds of workers. For each "Position" i want to count salary in diffrent way.
What i want to do in code:
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
Could you explain me, how to plan my DbContext
to achive, what i want to? Farmer
and Driver
need to have hard-coded values of propertys. When i let DbContext
like above in my code, i get two tables, dbo.Drivers
and dbo.Farmers
. If it will work in a way that i explained above? Is it possible in EF to block that hardcoded value in database and have it in every record of data i tables?
Upvotes: 0
Views: 3581
Reputation: 4220
Your Farmer
and Driver
classes have no new properties, just some constants for calculations. That is not the Model/Database layer's concern, it's the Services layer job.
My Suggestion:
public enum WorkerType
{
Farmer,
Driver
}
Worker Class:
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; }
}
And then you can have a service or extension method that calculates the salary, for example:
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;
}
}
}
Now you can get workers salary:
foreach(var worker in Workers)
var salary = worker.Salary();
The problem here is that every time your calculation constants change you need to change code and rebuild/republish. For that you can create a wage info table in your database and get those informations from there, and you can change them whenever you want.
Upvotes: 1