EF中

时间:2017-07-06 15:39:31

标签: c# entity-framework

在尝试学习实体框架时,我现在遇到了很多问题。 假设我有这个实体:

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

这两个实体完全不相关。这是Building实体:

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

当我尝试将建筑物添加到建筑群时,我的问题就出现了。在我的域模型中,我可以通过添加,修改或删除建筑物来修改等效的建筑物集合。但是,当我尝试通过存储库更新BuildingGroup时,建筑物将不会更新。

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

如果在调用Update()之前未将建筑物保存在数据库中,则此操作失败,这是正常的,因为建筑物可以独立生活。还必须为BuildingGroup(如果还有更多)的每个儿童集合进行此项处理,对于这些儿童的儿童集合,以及... ...

我注意到其他人在子对象中使用了外键约束(这里是Building),但我不能真的这样做,因为许多不相关的实体可以指向一个建筑物:我有一个很多导航属性。

是否有一种优雅的方式来管理引用对象,这些对象也可以独立于那些引用它们的人?

1 个答案:

答案 0 :(得分:0)

如果所有实体必须独立存在,但彼此之间存在关系,那么最好使用多对多关系。

按如下方式更改模型类,建筑物应包含一些建筑师和团体的集合。

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

如果使用实体类型配置,则可以按如下方式定义关系:

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