【问题标题】:C# How to change the loaded dbSet, with Include method depending on the request?C# 如何根据请求使用 Include 方法更改加载的 dbSet?
【发布时间】:2016-11-30 08:55:11
【问题描述】:

我知道堆栈溢出中有很多问题与我读过的几乎所有问题的主题相同,但它们让我对此更加困惑。

请看下面的代码

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

您是否注意到 2 个 if 语句之间的唯一变化只是 dbSet ?

我的问题是:有没有办法在不使用 if 的情况下达到相同的结果,我有 4 个地方实体,我刚刚发布了 2。如果客户要求在未来。

【问题讨论】:

    标签: c# entity-framework oop generics dbcontext


    【解决方案1】:

    这让我想知道如果您只为Place 使用一张表和一个实体会不会好得多,而不是将它们分布在显然数量可能会增加的多个表中...


    不过,解决方案可能是这样。 EF 实体类型始终是 Partial Classes,因此您可以添加它并让它们继承一个看起来像这样的接口IPlace(填写占位符):

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

    然后像这样缩短代码:

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

    【讨论】:

    • 赋值 DbSet&lt;IPlace&gt; dbSet = db.Doctors 将无法编译,因为 Doctors 的类型为 DbSet&lt;Doctor&gt; 并且 DbSet 在其泛型类型参数上不是协变的。
    【解决方案2】:

    我确信反射是你需要的,但我现在无法测试我的代码,所以我不确定我写的内容是否肯定会起作用..但它至少应该是这样的。

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

    【讨论】:

    • 是的,我认为反射是我需要的,但是您的代码不起作用,请您有时间尝试更新它,谢谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 2011-06-22
    • 2017-03-21
    • 2017-06-27
    • 2012-06-20
    • 2014-12-30
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多