简体   繁体   English

C#如何根据请求使用Include方法更改加载的dbSet?

[英]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 ? 您是否注意到2个if语句之间的唯一变化只是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. 我的问题是:是否有一种方法可以完全不使用if来实现相同的结果,我有4个place实体,我刚发布了2个。如果客户要求将来添加更多places,该怎么办?

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... 这让我想知道是否只用一个表和一个实体来Place会不会更好,而不是将它们分布在显然可能会增加数量的多个表上...


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): EF实体类型始终是部分类,因此您可以添加到其中,并使它们继承如下所示的接口IPlace (填充占位符):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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