简体   繁体   中英

C# How to change the loaded dbSet, with Include method depending on the request?

I know that there is many questions here in stack overflow that have the same topic I read almost all of them but they made me more confused about this.

Please Take a look at the code below

if (request.PlaceType == PlaceType.Doctor)
{
        var place = db.Doctors.Include(d => d.Reservations).FirstOrDefault(d => d.Id == request.PlaceId);
        place?.Reservations.Add(request.ToReservation(userId));
}
else if (request.PlaceType == PlaceType.Hospital)
{
        var place = db.Hospitals.Include(d => d.Reservations).FirstOrDefault(d => d.Id == request.PlaceId);
        place?.Reservations.Add(request.ToReservation(userId));
}

Did you notice that The only change between the 2 if statements is just the dbSet ?

My Question is : Is there a way to achieve the same result without using if at all, I have 4 places entities, I just posted 2. what If the client asked to add more places in the future.

This makes me wonder if you wouldn't be much better off with just one table and one entity for Place , instead of spreading them over multiple tables that apparently may grow in number...


Still, a solution could be this. EF entity types are always Partial Classes, so you can add to it and make them inherit an interface IPlace that looks like this (fill in the placeholders):

interface IPlace
{
    <<IdType>> Id { get; set; }
    <<ReservationType>> Reservations { get; set; }
    // perhaps more properties
}

Then shorten the code like this:

DbSet<IPlace> dbSet = null;
if (request.PlaceType == PlaceType.Doctor)
    dbSet = db.Doctors;
else if (request.PlaceType == PlaceType.Hospital)
    dbSet = db.Hospitals;

if (dbSet == null) throw new Exception("Unsupported PlaceType");

var place = dbSet.Include(d => d.Reservations).FirstOrDefault(d => d.Id == request.PlaceId);
place?.Reservations.Add(request.ToReservation(userId));

I am Sure reflection is what you need, but I can't test my code right now so I'm not sure if what I wrote will definitely work.. but it should be at the very least something like that.

     PropertyInfo[] placeTypes;
        placeTypes = typeof(PlaceType).GetProperties(BindingFlags.Public |
                                                  BindingFlags.Static);
var requestedType = placeTypes.SingleOrDefault(x=> x == request.PlaceType);

PropertyInfo context = typeof(dbContext).GetPropertie(requestedType.Name + "s");

var place = context.Include(d => d.Reservations).FirstOrDefault(d => d.Id == request.PlaceId);
        place?.Reservations.Add(request.ToReservation(userId));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM