简体   繁体   中英

Entity Framework relationship 0..1 with 1..* back link

I have two objects in my Entity Framework POCO classes called Lifeboat and Sighting

Sighting has a 1..* relationship with Lifeboat and this seems to work fine (with a link table of SightingLifeboats

I now also need to back reference that relationship so I need a link from Lifeboat to Sighting which will be 0..*

I have tried to do the reverse and tried making one virtual but this hasnt worked, maybe i need more fluent coding?

My Lifeboat Class:

public class Lifeboat : EntityBase
{
    public Lifeboat()
    {
        Sightings = new List<Sighting>();
    }

    public string CurrentName { get; set; }

    //A Lifeboat Ownes 0:* Sightings
    public List<Sighting> Sightings { get; set; }
    //public virtual Sighting Sightings { get; set; }

    //Called from Context Class OnModelCreating
    public static void LifeboatEntityConfiguration(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Lifeboat>().HasMany(x => x.Sightings).WithMany();
    }
}

And Sighting Class

public class Sighting : EntityBase
{
    public Sighting()
    {
        Lifeboats = new List<Lifeboat>();
        TimeSeen = DateTime.Now.Date;
    }

    public string Location { get; set; }

    //A Sighting has 1..* Lifeboats (Not Owned)
    public List<Lifeboat> Lifeboats { get; set; }
    //public virtual Lifeboat Lifeboat { get; set; }

    public static void SightingEntityConfiguration(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Sighting>().HasMany(x => x.Lifeboats).WithMany();
    }

}

That is not the proper way to configure a many to many relationship between Lifeboat and Sighting . If you remove the Fluent Api configurations you already have, by default, EF will create a third joining table, SightingLifeboats , which will consist of the PK of both the tables. That is because you have a collection navigation property in each entity. But you can configure explicitly that relationship using Fluent Api:

 modelBuilder.Entity<LifeBoat>()
             .HasMany<Sighting >(l => l.Sightings)
             .WithMany(s => s.LifeBoats)
             .Map(cs =>
                      {
                         cs.MapLeftKey("LifeBoatRefId");
                         cs.MapRightKey("SightingId");
                         cs.ToTable("SightingLifeboats");
                      });

This way you can change the name of the junction table and specify the FK property names, in case you need to change them.

Another thing, I recommend to change your collection properties to virtual .If you make all your properties virtual then EF will generate proxy classes at runtime that derives from your POCO classes, these proxies allow EF to find out about changes in real time rather than having to capture the original values of your object and then scan for changes when you save.

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