Return DbSet based on selection

asp.net-core asp.net-core-mvc c# dbset entity-framework-core

Question

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:

  • Part
    • PartA
    • PartB

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?

1
0
5/10/2017 5:05:44 PM

Accepted Answer

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();

}
1
5/10/2017 8:12:23 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow