首页 > 解决方案 > 实体框架核心变更跟踪器

问题描述

请帮助我理解 Entity Framework Core v2.2.2 的奇怪行为我有类 Country,它包含 Regions 的集合,每个 Region 指的是它的所有者 - Country,而且 Region 可能包含 SubRegions 的集合,每个 SubRegion 指的是它的 SuperiorRegion .

请参阅下面的 UML 图。 领域模型

这是代码:

类国家

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

这是我得到的结构: 对象图

检查:

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

现在更有趣了。我创建 DbContext…</p>

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

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

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    }
}

......并将 Country 连接到它:

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!!!!!!!

这就是我在图表上得到的: 对象图

实际上,问题是:如何使 SubRegion 不被添加到 Country 的 Region 集合中?

标签: entity-frameworkentity-framework-corechange-tracking

解决方案


您的问题是 Regions 和 SubRegions 与 Country 的两种关系混淆了 EF。当您要求 EF 为您检索区域时,它的作用是搜索所有将其国家作为您要导航的区域的区域,这意味着子区域也满足此条件。

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


推荐阅读