EF Core 3.1 Отношение один к одному, ссылка на объект не установлена ​​на экземпляр объекта - PullRequest
0 голосов
/ 02 марта 2020

Я пытаюсь здесь преобразовать один из моих старых проектов, написанных в 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>

1 Ответ

1 голос
/ 02 марта 2020

Ошибка указывает, что Model.Item, вероятно, ноль. Попробуйте Загрузка связанных данных в вашем хранилище GetAdvertisment метод с использованием Include подобно

public async Task<T> GetAdvertisment(int id)
{
    return await _context.advertisments
                         .Include(a => a.Item)                         
                         .SingleOrDefaultAsync(s => s.Id == id);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...