Я пытаюсь здесь преобразовать один из моих старых проектов, написанных в Java, Hibernate, в ASP. NET Core 3, EF Core 3.1
То, что я пытаюсь сделать, это: сопоставьте класс Advertisment с абстрактным классом и его производными частями, используя отношение один к одному и стратегию TPH. Сопоставление иерархии объектов с TPH работало нормально, но отношения между ним и классом Advertisment вызывают некоторые проблемы, в основном, когда я пытаюсь получить доступ к этому одному элементу рекламы.
Сообщение об ошибке
NullReferenceException: Object reference not set to an instance of an object.
AspNetCore.Views_Home_Index.ExecuteAsync() in Index.cshtml
<h1>@Model.Id @(((AutoItem)(Model.Item)).AdvertismentId)</h1>
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, bool invokeViewStarts)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Вот соответствующий код:
Абстрактный базовый класс
[Table("items")]
public abstract class ItemCategory
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public double? Price { get; set; }
[MaxLength(50)]
public string? Brand { get; set; }
[MaxLength(500,ErrorMessage =" Description can contain maximum 500 characters")]
[MinLength(20, ErrorMessage = " Description must contain maximum 20 characters")]
[Required]
public string Description { get; set; }
public int AdvertismentId { get; set; }
public Advertisment Advertisment { get; set; }
}
Бетонная деталь
[Table("items")]
public class AutoItem : ItemCategory
{
[Display(Name="Production year")]
[DisplayFormat(DataFormatString ="{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? ProductAge { get; set; }
public int? Mileage { get; set; }
}
Класс рекламы
[Table("advertisments")]
public class Advertisment
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[MaxLength(50)]
public string Title { get; set; }
public DateTime PostDate { get; set; }
public string? Picture { get; set; }
public ItemCategory Item { get; set; }
}
Конфигурация в классе DbContext
public DbSet<ItemCategory> Items { get; set; }
public DbSet<AutoItem> AutoItems { get; set; }
public DbSet<Advertisment> advertisments { get; set;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Define the TPH using Fluent.API
modelBuilder.Entity<ItemCategory>()
.ToTable("items")
.HasDiscriminator<string>("item_type")
.HasValue<AutoItem>("auto_type");
modelBuilder.Entity<Advertisment>()
.ToTable("advertisments");
// One - to - One relationship between ItemCategory <-> Advertisment
modelBuilder.Entity<Advertisment>()
.HasOne(p => p.Item)
.WithOne(a => a.Advertisment)
.HasForeignKey<ItemCategory>(ic => ic.AdvertismentId)
.OnDelete(DeleteBehavior.Cascade);
}
Метод действия
public async Task<IActionResult> Index()
{
// fetches the data using context.class.FindAsync()
var ad = await advertismentRepository.GetAdvertisment(1);
return View(ad);
}
Просмотр бритвы - проблема возникает здесь, когда я пытаюсь получить доступ Пункт этой рекламы
@model Advertisment
@{
ViewBag.Title = "Home Page";
}
<div class="text-center">
<h1>@Model.Id @(((AutoItem)(Model.Item)).AdvertismentId)</h1>
</div>