首页 > 解决方案 > EF TPT 继承和自引用

问题描述

我有以下 EF 实体类的结构:

    public abstract class CalendarItem
    {
        public Guid CalendarItemId { get; set; }
        public Guid? ParentCalendarItemId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }

        public virtual CalendarItem ParentCalendarItem { get; set; }
        public virtual ICollection<CalendarItem> ChildCalendarItems { get; set; }
    }

    public class CalendarSlot : CalendarItem
    {
        public bool IsAvailable { get; set; }
    }

    public class CalendarSession : CalendarEvent
    {
        public DateTimeOffset StartDateTime { get; set; }
        public DateTimeOffset EndDateTime { get; set; }
    }

映射配置如下:

    public class CalendarItemMap
    {
        public static void Map(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<CalendarItem>().ToTable("CalendarItem");
            modelBuilder.Entity<CalendarItem>().HasKey(t => t.CalendarItemId);
            modelBuilder.Entity<CalendarItem>().HasOne(ci => ci.ParentCalendarItem)
                .WithMany(cs => cs.ChildCalendarItems).HasForeignKey(cs => cs.ParentCalendarItemId);
        }
    }

使用 DbSets 作为:

        public DbSet<CalendarItem> CalendarItems { get; set; }
        public DbSet<CalendarSession> CalendarSessions { get; set; }
        public DbSet<CalendarSlot> CalendarSlots { get; set; }

我的问题是如何在提供继承的情况下正确组织基类的自引用(树)结构。所有类型的实体,即 CalendarSlot 和 CalendarSession 都应该有自己的引用,CalendarItem 不能创建为实例。在数据库中,树结构在 CalendarItem 表中实现。CalendarSlot/CalendarSession 表与 CalendarItem 具有 1-1 关系。

问题是,在我的代码中,我有一个通用方法的位置,它将模型转换为 API 的合同:

        internal static TContract ToCalendarItem<TContract, TModel>(TModel calendarItemModel)
            where TContract : Contract.CalendarItem, new()
            where TModel : Model.CalendarItem
        {
            return new()
            {
                CalendarItemId = calendarItemModel.CalendarItemId,
                Name = calendarItemModel.Name,
                Description = calendarItemModel.Description,
                ParentCalendarItem = calendarItemModel.ParentCalendarItem != null ? ToCalendarItem<TContract, TModel>(calendarItemModel.ParentCalendarItem) : null
            };
        }

并在行中

ParentCalendarItem = calendarItemModel.ParentCalendarItem != null ? ToCalendarItem<TContract, TModel>(calendarItemModel.ParentCalendarItem) : null

我有一个错误"Argument 1: Cannot convert from 'Model.CalendarItem' to TModel"。我如何告诉系统calendarItemModel.ParentCalendarItem应该始终是 TModel (从 派生的类Model.CalendarItem)?

我在这里做错了什么?先感谢您。

标签: c#entity-framework-core.net-5

解决方案


推荐阅读