简体   繁体   中英

EF Core 3.0 : Multiple navigation properties in an entity

Here are the 2 entities I have defined and I am using EF Core 3.0. Whenever I try to create a new migration, I keep getting an error saying can not have the same navigation property in multiple relationships.

Me being a noob in EF Core, any pointers in resolving this issue would be very helpful.

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; }        
    }

As the EF Core tools will tell you:

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.

There are two simple solutions to this issue:

Use two navigation properties on the EventContext type

If you actually need the navigation property on EventContext and not just on Event , then the following will work:

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);
            });
    }
}

Use a one-way navigation property

If you can live without the navigation property on EventContext and are happy to just use the one on Event , then just remove it from EventContext and the following will work for you as well:

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);
            });
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM