首页 > 解决方案 > LINQ 包含和继承

问题描述

我有一个 WEB API 项目,它使用 Database First 模型。我有基类Building实体和MultiApartmentBuilding从 Building 继承的实体。我也有一个Apartment实体,它与Building实体以一对多的关系连接。我想通过给定的公寓 ID 获得特定的公寓,并包含一些MultiApartmentBuilding信息。

到目前为止,我已经尝试通过Include()LINQ 方法达到理想的结果,但是遇到了一个我无法包含的问题MultiapartmentBuilding

这是我的Building课。

public abstract class Building
{
    public int Id { get; set; }
    public BuildingState State { get; set; }
    public BuildingType Type { get; set; }
    public int AddressId { get; set; }
    public Address Address { get; set; }
    public MultilingualString Description { get; set; }
    public string MainImg { get; set; }
    public bool IsBuilt { get; set; }
}

这是我的MultiApartmentBuilding课。

public class MultiApartmentBuilding : Building
{
    public int GroundFloorCount { get; set; }
    public double FloorHeight { get; set; }
    public int? WallId { get; set; }
    public Wall Wall { get; set; }       
}

这是我的Apartment课。

public class Apartment : EntityBase
{
    public int Id { get; set; }

    public int BuildingId { get; set; }
    public Building Building { get; set; }
    public Common.Enums.ApartmentState State { get; set; }
    public AccessibilityState Accessibility { get; set; }
    public int Floor { get; set; }
    public bool IsPentHouse { get; set; }
}

这是我的 LINQ 查询,应该返回公寓。

var apartment = _context.Apartments
    .Where(id => id.Id == apartmentId)
    .Include(building => building.Building)
        .ThenInclude(address => address.Address)
        .ThenInclude(city => city.City)
        .ThenInclude(cityName => cityName.Name)
   .Include(district => district.Building.Address.District)
        .ThenInclude(districtName => districtName.Name)
   .Include(street => street.Building.Address.Street)
   .Include(condPrices => condPrices.ConditionPrices)
        .ThenInclude(condition => condition.Condition)
        .ThenInclude(conditionName => conditionName.Name)
        .ThenInclude(conditionNameTranslation => conditionNameTranslation.Translations)
   .Include(builder => builder.Building.Builder)
        .ThenInclude(brandName => brandName.BrandName)
        .ThenInclude(brandNameTrans => brandNameTrans.Translations)
    .Include(builderBussinesAddress => builderBussinesAddress.Building.Builder.BusinessAddress)
         .ThenInclude(tranlsations => tranlsations.Translations)
   .Include(descriptipon => descriptipon.Description)
        .ThenInclude(descriptionName => descriptionName.Translations)

此查询的问题是我无法访问MultiApartmentBuilding字段。我只能访问Building字段,尽管MultiApartmentBuilding是从Building. 有没有办法也可以访问MultiApartmenBuilding字段?

标签: c#.netlinq

解决方案


包括Building也将包括MultiApartmentBuilding条目(实际上所有类型派生自Building)。

您可以使用 C# 7.0 的模式匹配同时进行测试和强制转换(apartments查询结果在哪里):

foreach (Apartment apartment in apartments) {
    // Access common Building field.
    Console.WriteLine(apartment.Building.Id);

    // Access specialized field from derived building type.
    if (apartment.Building is MultiApartmentBuilding maBuilding) {
        Console.WriteLine(maBuilding.GroundFloorCount);
    }
}

如果你有很多类型的建筑物,你可以在 switch 语句中使用模式匹配

switch (apartment.Building)
{
    case MultiApartmentBuilding maBuilding:
        Console.WriteLine(maBuilding.GroundFloorCount);
        break;
    case Igloo igloo:
        Console.WriteLine(igloo.SnowQuality);
        break;
    default:
        Console.WriteLine("all other building types");
        break;
}

推荐阅读