Entity Framework Core Navigation Properties Error

.net c# entity-framework entity-framework-core

Question

I'm trying to make a simple app to try Entity Framework Core, but i a have problem with setting up relations between entities. My entities:

public class Card
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Adress { get; set; }
    public DateTime DoB { get; set; }
    public DateTime DoS { get; set; }
    public User Portal { get; set; }
    public List<Reservation> Res { get; set; }
}
public class Doctor
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Email { get; set; }
    public TimeSpan Start_Working { get; set; }
    public TimeSpan End_Working { get; set; }
    public List<Reservation> Reservations { get; set; }
    public int SpecID { get; set; }
    public Spec Spec { get; set; }
}
public class Reservation
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public DateTime DoR { get; set; }
    public string Info { get; set; }
    public int CardID { get; set; }
    public Card Card_Nav_R { get; set; }
    public int DoctorID { get; set; }
    public Doctor Doctor { get; set; }
}
public class Spec
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Doctor> Doctors { get; set; }
}
public class User
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public int CardID { get; set; }
    public Card Card { get; set; }
}

And a configuration class where i tried to set up relations:

class ApplicationContext:DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Card> Cards { get; set; }
    public DbSet<Reservation> Reservations { get; set; }
    public DbSet<Doctor> Doctors { get; set; }
    public DbSet<Spec> Specs { get; set; }

    public ApplicationContext()
    {
        Database.EnsureCreated();
    }
    protected override void OnModelCreating(ModelBuilder ModelBuilder)
    {
          ModelBuilder.Entity<User>().HasKey(u => u.Id);
          ModelBuilder.Entity<Card>().HasKey(c => c.Id);
          ModelBuilder.Entity<Doctor>().HasKey(d => d.Id);
          ModelBuilder.Entity<Spec>().HasKey(s => s.Id);
          ModelBuilder.Entity<Reservation>().HasKey(r => r.Id);

          ModelBuilder.Entity<User>().Property(u => u.Email).IsRequired();
          ModelBuilder.Entity<User>().Property(u => u.Password).IsRequired();

          ModelBuilder.Entity<Card>().Property(c => c.Name).IsRequired();
          ModelBuilder.Entity<Card>().Property(c => c.Surname).IsRequired();
          ModelBuilder.Entity<Card>().Property(c => c.DoB).IsRequired();
          ModelBuilder.Entity<Card>().Property(c => c.Adress).IsRequired();

          ModelBuilder.Entity<Doctor>().Property(d => d.Name).IsRequired();
          ModelBuilder.Entity<Doctor>().Property(d => d.Surname).IsRequired();
          ModelBuilder.Entity<Doctor>().Property(d => d.Spec).IsRequired();
          ModelBuilder.Entity<Doctor>().Property(d => d.Email).IsRequired();
          ModelBuilder.Entity<Doctor>().Property(d => d.Start_Working).IsRequired();
          ModelBuilder.Entity<Doctor>().Property(d => d.End_Working).IsRequired();

          ModelBuilder.Entity<Reservation>().Property(r => r.Info).IsRequired();
          ModelBuilder.Entity<Reservation>().Property(r => r.Card_Nav_R).IsRequired();
          ModelBuilder.Entity<Reservation>().Property(r => r.Doctor).IsRequired();
          ModelBuilder.Entity<Reservation>().Property(r => r.DoR).IsRequired();

        ModelBuilder.Entity<Spec>().Property(s => s.Name).IsRequired();

          ModelBuilder.Entity<Doctor>().HasOne<Spec>(d=>d.Spec).WithMany(s => s.Doctors).HasForeignKey(d => d.SpecID);
          ModelBuilder.Entity<User>().HasOne<Card>(u => u.Card).WithOne(c => c.Portal).HasForeignKey<User>(u => u.CardID);
          ModelBuilder.Entity<Reservation>().HasOne<Card>(r => r.Card_Nav_R).WithMany(c => c.Res).HasForeignKey(r => r.CardID);
          ModelBuilder.Entity<Reservation>().HasOne<Doctor>(r => r.Doctor).WithMany(d => d.Reservations).HasForeignKey(r => r.DoctorID); 

    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=Simple_Try;Trusted_Connection=True;");
    }
}

So, when i tried to add migration or add something to database i saw this error:

System.InvalidOperationException: 'The property or navigation 'Spec' cannot be added to the entity type 'Doctor' because a property or navigation with the same name already exists on entity type 'Doctor'.'

I really don't know how to fix this, i tried to use annotations instead of Fluent API, but had the same result.

1
1
8/19/2018 4:19:19 PM

Accepted Answer

The cause of the exception is the following line:

ModelBuilder.Entity<Doctor>().Property(d => d.Spec).IsRequired();

because Doctor.Spec is a navigation property

public class Doctor
{
    // ...
    public Spec Spec { get; set; }
}

and navigation properties cannot be configured via Property fluent API.

So simply remove that line. Whether reference navigation property is required or optional is controlled via relationship configuration. In this case

ModelBuilder.Entity<Doctor>()
   .HasOne(d => d.Spec)
   .WithMany(s => s.Doctors)
   .HasForeignKey(d => d.SpecID)
   .IsRequired(); // <--

although the IsRequired is automatically derived from the FK property type - since SpecID is non nullable, then the relationship is required.

For more info, see Required and Optional Properties and Required and Optional Relationships documentation topics.

2
8/19/2018 4:16:29 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow