EF Core 3.0:实体中的多个导航属性

EF Core 3.0 : Multiple navigation properties in an entity

这是我定义的 2 个实体,我使用的是 EF Core 3.0。 每当我尝试创建一个新的迁移时,我总是收到一条错误消息,说在多个关系中不能有相同的导航 属性。

我是 EF Core 的新手,任何解决此问题的建议都会非常有帮助。

public class Event
    {
        public Guid Id { get; set; }
        public EventContext StartContext { get; set; }
        
        public EventContext EndContext { get; set; } 
        public Guid CreatedBy { get; set; }
        public Guid UpdatedBy { get; set; }
        
    }

    public class EventContext
    {
        public Guid Id { get; set; }
        public Guid EventId { get; set; } //fk
        public Event Event { get; set; }
        public DateTime ApplicableDate { get; set; }        
    }

EF Core 工具会告诉您:

Cannot create a relationship between 'Event.EndContext' and 'EventContext.Event', because there already is a relationship between 'Event.StartContext' and 'EventContext.Event'. Navigation properties can only participate in a single relationship.

这个问题有两个简单的解决方案:

EventContext 类型上使用两个导航属性

如果您确实需要 EventContext 上的导航 属性 而不仅仅是 Event 上的导航 属性,那么以下方法将起作用:

public class Event
{
    public Guid Id { get; set; }
    public Guid CreatedBy { get; set; }
    public Guid UpdatedBy { get; set; }
    
    public EventContext StartContext { get; set; }
    public EventContext EndContext { get; set; }
}

public class EventContext
{
    public Guid Id { get; set; }
    public Guid EventId { get; set; }
    public DateTime ApplicableDate { get; set; }
    
    // One navigation property for each corresponding navigation property on `Event`.
    public Event StartContextEvent { get; set; }
    public Event EndContextEvent { get; set; }
}

public class Context : DbContext
{
    public DbSet<Event> Events { get; set; }
    public DbSet<EventContext> EventContexts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Event>(
            entity =>
            {
                entity.HasOne(e => e.StartContext)
                    .WithOne(e => e.StartContextEvent)
                    .HasForeignKey<EventContext>(e => e.EventId);

                entity.HasOne(e => e.EndContext)
                    .WithOne(e => e.EndContextEvent)
                    .HasForeignKey<EventContext>(e => e.EventId);
            });
    }
}

使用单向导航属性

如果您可以在 EventContext 上没有导航 属性 并且愿意只使用 Event 上的导航,那么只需将其从 EventContext 中删除,然后以下内容也适用于您:

public class Event
{
    public Guid Id { get; set; }
    public Guid CreatedBy { get; set; }
    public Guid UpdatedBy { get; set; }
    
    public EventContext StartContext { get; set; }
    public EventContext EndContext { get; set; }
}

public class EventContext
{
    public Guid Id { get; set; }
    public Guid EventId { get; set; }
    public DateTime ApplicableDate { get; set; }
}

public class Context : DbContext
{
    public DbSet<Event> Events { get; set; }
    public DbSet<EventContext> EventContexts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Event>(
            entity =>
            {
                entity.HasOne(e => e.StartContext)
                    .WithOne()
                    .HasForeignKey<EventContext>(e => e.EventId);

                entity.HasOne(e => e.EndContext)
                    .WithOne()
                    .HasForeignKey<EventContext>(e => e.EventId);
            });
    }
}