简体   繁体   中英

Independent child object with references from multiples parents in EF

I'm having quite the issue right now while trying to learn Entity Framework. Let's say I have this entity:

public class BuildingGroup {
    public int ID { get; set; }
    public string NameOfManager { get; set; }

    public virtual ICollection<Building> Buildings { get; set; }
}

And also this entity.

public class Architect {
    public int ID { get; set; }
    public string Email { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Building> BuildingsBeingWorkedOn { get; set; }
}

These two entities are completely unrelated. Here's the Building entity:

public class Building {
    public int ID { get; set; }
    public string Address { get; set; }
}

My problem happens when I try to add a building to, say a BuildingGroup. In my domain model, I can modify the equivalent collection of buildings, by adding, modifying or removing buildings. However, when I try to update BuildingGroup through a repository, the buildings will not be updated.

public void Update(BuildingGroup buildingGroup) {
    var buildingGroupEntity = _context.BuildingGroups.Single(b => b.ID == buildingGroup.ID);

    // This will not map the Building collection
    context.Entry(buildingGroupEntity).CurrentValues.SetValues(buildingGroup);

    // My attempt at mapping the buildings
    buildingGroupEntity.Buildings.Clear();
    buildingGroup.Buildings.ToList().ForEach(b => buildingGroupEntity.Buildings.Add(_context.Buildings.Single(x => x.ID == b.ID)));

    _context.Entry(buildingGroupEntity).State = EntityState.Modified;
}

This fails if the building were not saved in the database prior to the call to Update() , which is normal since buildings can live independently. It must also be done for every child collection of BuildingGroup (if there were more), and for child collections of these children, well...

I have noticed other people use a foreign key constraint in the child object (here, Building ), but I can't really do that since many unrelated entities can point to a building: I'd have a lot of navigation properties.

Is there a graceful way to manage referencing objects that can also live independently from those who hold references to them?

If all the entities have to exist independently, yet have relationships with each other, it's better to use many-to-many relationship.

Change your model classes as follows, the Building should contain a couple of collections for architects and groups.

public class BuildingGroup
{
    public int ID { get; set; }
    public string NameOfManager { get; set; }

    public virtual ICollection<Building> Buildings { get; set; }
}

public class Architect
{
    public int ID { get; set; }
    public string Email { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Building> BuildingsBeingWorkedOn { get; set; }
}

public class Building
{
    public int ID { get; set; }
    public string Address { get; set; }

    public virtual ICollection<Architect> Architects { get; set; }
    public virtual ICollection<BuildingGroup> BuildingGroups { get; set; }
}

If you use entity type configuration, you could define the relationship as follows:

public class MyDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Building>().HasMany(it => it.Architects).WithMany(it => it.BuildingsBeingWorkedOn);
        modelBuilder.Entity<Building>().HasMany(it => it.BuildingGroups).WithMany(it => it.Buildings);

        base.OnModelCreating(modelBuilder);
    }
}

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