I'm writing an ASP.NET Core MVC web app that is a tool for handling a parts database. What I want is for the user to select a Part and then that will do some action, like delete that part from it's DB. However, I want this to be a generic action used by all the parts.
I have a class hierarchy which is:
What I need is some method that I can call that will get the DbSet that my part belongs to. This is an example of what I'm looking to do:
Models
public class Part
{
public Nullable<int> ID { get; set; }
public string Brand { get; set; }
}
public class PartA : Part
{
public int Length { get; set; }
public List<Image> Images { get; set; }
}
public class PartB : Part
{
public int Durability { get; set; }
}
public class Image
{
public Nullable<int> ID { get; set; }
public string ImagePath { get; set; }
}
PartsDbContext
public class PartsDbContext : DbContext
{
public DbSet<PartA> PartAs { get; set; }
public DbSet<PartB> PartBs { get; set; }
}
PartsController
public IActionResult DeletePart (string partType, int id)
{
var partSet = GetDbSet(partType);
var part partSet.FirstOrDefault(e => e.ID == id);
if (part != null)
{
partSet.Remove(part);
_context.SaveChanges();
}
}
//function to find and return DbSet of the selected type
private DbSet<Part> GetDbSet (string partType)
{
switch (partType)
{
case "PartA":
return _context.PartAs;
case "PartB":
return _context.PartBs;
}
return null;
}
Now obviously this doesn't work because the compiler will complain that:
You can't convert type DbSet<PartA> to type DbSet<Part>
Anyone know how I might go about doing this?
This is really hacky, but sort of works.
public IActionResult DeletePart (string partType, int id)
{
Type type = GetTypeOfPart(partType);
var part = _context.Find(type, id);
var entry = _context.Entry(part);
entry.State = EntityState.Deleted;
_context.SaveChanges();
}
However, you really should just use polymorphism and generic abstract Controllers.
EDIT You can also use Explicit Loading for this.
private void LoadRelatedImages(IPart part)
{
_context.Entry(part)
.Collection(p => p.Images)
.Load();
}