0

I'm trying to organize one to one relationship using EF Code First for the following classes. Bus is a principal class and Schedule is a dependent one.

public class Bus
{
    public int Id { get; set; }
    public virtual Schedule Schedule { get; set; }
}

public class Schedule
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime BusRouteStartTime { get; set; }
    public DateTime BusRouteEndTime { get; set; }
    public DateTime ArrivalTime { get; set; }
    public DateTime DepartureTime { get; set; }

    [ForeignKey("Bus")]
    public int BusId { get; set; }
    public virtual Bus Bus { get; set; }
}

I made this classes using this tutorial. When I do Enable-Migrations in PCM and I get this error:

Bus_Schedule_Target: : Multiplicity is not valid in Role 'Bus_Schedule_Target' in relationship 'Bus_Schedule'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

I google this error and find this solution. I modify OnModelCreating():

modelBuilder.Entity<Schedule>().HasKey(s => s.Id);
modelBuilder.Entity<Bus>()
            .HasRequired(s => s.Schedule)
            .WithRequiredPrincipal(b => b.Bus);

Unfortunately it didn't help. I continue to google when I understand that by default dependent class's Id must be primary and foreign key at the same time. It doesn't fit me, because it may cause of problems with drop tables later, for instance in cascading delete.

Please help me, I understand that it is some kind of duplicated question, but it will be really better, if it can be done this way.

Community
  • 1
  • 1
QuarK
  • 1,162
  • 2
  • 12
  • 27

1 Answers1

0

You can perform one trick - create one-to-many relationship, but mask it as one-to-one:

public class Bus
{
    public int Id { get; set; }        
    [Obsolete]
    public virtual ICollection<Schedule> Schedules { get; set; }

    //Here I implemented primitive logic, you should expand it by your own.
    [NotMapped]
    public Schedule Schedule {
        get {
            return Schedules.FirstOrDefault();
        }
        set {                
            Schedules.Add(value);
        }
    }
}

public class Schedule
{
    //other stuff...

    [Index(IsUnique = true)]//This index will prevent from inserting duplicates
    public int BusId { get; set; }
    public virtual Bus Bus { get; set; }
} 

Now you can work with this classes as you desired initial, all what you should do is ignore Schedules property, that is why I marked it with Obsolete attribute for reminding about it.

Slava Utesinov
  • 13,410
  • 2
  • 19
  • 26