Entity Framework 核心(代码优先)不会插入到相关表中

Entity Framework Core (Code First) won't insert into dependent tables

我有一个使用 Entity Framework Core 3.1.5 的应用程序 (.NET Framework 4.8)。 (我不敢升级,因为我觉得这可能会破坏其他依赖项 - 我很高兴它能按原样工作。)

我正在使用“代码优先”方法将数据从 SharePoint 导出到 SQL tables。 某些 SharePoint“列表”(tables 的 SharePoint 概念)可以包含 M:N 映射,我必须将其分成单独的 SQL tables。

一些代码:


    // Base class for all parent tables
    internal abstract class SharePointListModel
    {
        [SharePointColumn("ID")]
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int Id { get; set; }

        public virtual void PostProcess()
        {
        }
    }

    // Base class for all child tables
    internal abstract class AdditionalTableModel
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
    }

    // This is the child table, which is never inserted
    [Table("MyMappingTable", Schema = "myschema")]
    internal class MyMappingTable : AdditionalTableModel
    {
        // This points to a third table, but it could really
        // be any value. It could also be a string or BLOB etc.
        public int OtherTableId { get; set; }
    }

    // This is the parent table, which is inserted correctly
    [Table("MySharePointTable", Schema = "myschema")]
    internal class MySharePointTable : SharePointListModel
    {
        [SharePointColumn("SharePointLookupColumn", UseId = true)]
        [NotMapped]
        public int[] OtherTableIds { get; set; }

        public List<MyMappingTable> Mappings { get; set; } // Making the property virtual doesn't change anything either

        public override void PostProcess()
        {
            Mappings = OtherTableIds?.Select(x => new MyMappingTable { OtherTableId = x }).ToList();
        }
    }

Entity Framework 似乎理解这一点,因为 dbContext.CreateTable() 创建了一个包含三列的 table “MyMappingTable”(尽管只定义了两个属性):Id、OtherTableId (实际上是外键,但 EF 不知道)和 MySharePointTableId(外键).

但是当我像这样插入数据时,M:N 映射 table (MyMappingTable) 仍然是空的:

IList<MySharePointTable> = LoadSharePointTable();
dbContext.AddRange(data);
dbContext.SaveChanges();

显式映射 parent 也无济于事:

    [Table("MyMappingTable", Schema = "myschema")]
    internal class MyMappingTable : AdditionalTableModel
    {
        public virtual MySharePointTable Parent { get; set; }
        public int OtherTableId { get; set; }
    }

// [...]
        public override void PostProcess()
        {
            Mappings = OtherTableIds?.Select(x => new MyMappingTable { Parent = this, OtherTableId = x }).ToList();
        }

我也试过显式插入依赖行,但这并没有改变任何东西:

IList<MySharePointTable> = LoadSharePointTable();
dbContext.AddRange(data);
IEnumerable<MyMappingTable> dependentRows = data.SelectMany(x => x.Mappings ?? Enumerable.Empty<MyMappingTable>());
dbContext.AddRange(dependentRows);
dbContext.SaveChanges();

或者像这样,但这也没有改变任何东西,child table 仍然是空的:

IList<MySharePointTable> = LoadSharePointTable();
dbContext.AddRange(data);
IEnumerable<MyMappingTable> dependentRows = data.SelectMany(x => x.Mappings ?? Enumerable.Empty<MyMappingTable>());
dbContext.Set<MyMappingTable>().AddRange(dependentRows);
dbContext.SaveChanges();

此处的插入代码略有简化,因为我实际上是将反射用于通用方法,但我认为这无关紧要。

我做错了什么?

确定一下,这两个名字不应该匹配吗?因为一切似乎都是正确的,所以您不需要为子实体 EF 处理它而显式插入。

呃。好像我一直在看错误的数据库...