实体框架核心ChangeTracker

时间:2019-03-05 13:57:42

标签: entity-framework entity-framework-core change-tracking

请帮助我了解Entity Framework Core v2.2.2的奇怪行为 我有一个“国家”类,其中包含“区域”的集合,每个“区域”均指其所有者-“国家”,并且“区域”也可以包含“子区域”的集合,每个“子区域”均指其上级区域。

请参阅下面的UML图。 Domain model

这是代码:

国家/地区类别

public class Country
{
    public Country(string name)
    {
        Name = name;
        Regions = new List<Region>();
    }

    // for EF
    protected Country()
    {
    }

    public int Id { get; set; }

    public string Name { get; set; }

    public IList<Region> Regions { get; set; }

    public Region CreateRegion(string name)
    {
        var region = new Region(name, this);

        Regions.Add(region);

        return region;
    }
}

地区类别

public class Region
{
    public Region(string name, Country country)
    {
        Name = name;
        Country = country;
        SubRegions = new List<Region>();
    }

    // for EF
    protected Region()
    {
    }

    public int Id { get; set; }

    public string Name { get; set; }

    public Country Country { get; set; }

    public IList<Region> SubRegions { get; set; }

    public Region SuperiorRegion { get; set; }

    public Region CreateSubRegion(string name)
    {
        var region = new Region(name, Country);

        SubRegions.Add(region);
        region.SuperiorRegion = this;

        return region;
    }
}

然后我创建一棵树(到目前为止一切顺利):

var country = new Country("Best Country of the World");
var beachesRegion = country.CreateRegion("Region with beaches");
var hotelsRegion = beachesRegion.CreateSubRegion("Region with hotels");
var workRegion = country.CreateRegion("Region with hard work");

这是我得到的结构: Object diagram

检查:

Console.WriteLine(country.Regions.Count); // 2

现在更有趣了。 我创建了DbContext ...

public class CountryContext : DbContext
{
    public CountryContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<Country> Countries { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    }
}

…并将“国家/地区”与其连接:

var options = new DbContextOptionsBuilder<CountryContext>()
            .UseInMemoryDatabase(databaseName: "Countries")
            .Options;

using (var db = new CountryContext(options))
{
    db.Countries.Add(country);
}

这次

Console.WriteLine(country.Regions.Count); //3!!!!!!!

这是我在图表上看到的: Object Diagram

实际上,问题是:如何使该子区域不添加到“国家/地区”的Region集合中?

1 个答案:

答案 0 :(得分:1)

您的问题是,地区和子地区与国家/地区的两种关系使EF变得混乱。 当您要求EF为您检索地区时,它会搜索要导航其国家(地区)的所有地区,这意味着子地区也要满足此条件。

要解决此问题,您必须从Country中删除Region属性。或者,您创建两个类RegionSubRegion,其中Region具有Country属性(如果层次结构不能超过两个级别,则也可能没有SuperiorRegion属性) 。并且SubRegion不具有Country属性。