C# 将代码植入第一个数据库会导致错误-->;实体类型'的种子实体$名称';无法添加,因为它具有导航'$名称';设置

C# 将代码植入第一个数据库会导致错误-->;实体类型'的种子实体$名称';无法添加,因为它具有导航'$名称';设置,c#,.net-core,entity-framework-core,C#,.net Core,Entity Framework Core,我对代码优先方法和.NETCore3EF非常陌生。经过多年的良好的旧数据库项目和纯SQL,昨天刚刚开始。出于测试目的,我想在数据库中预先填充一组条目以进行测试。然而,这似乎并不像我预期的那样有效。我已经移动了一些东西,但错误信息不会消失: 无法添加实体类型“SourceColumnName”的种子实体 因为它设置了导航“SourceColumn”。播种 需要将相关实体种子添加到的关系 'SourceColumn'并指定外键值{'SourceColumnID'}。 考虑使用“dBraveTopSt

我对代码优先方法和.NETCore3EF非常陌生。经过多年的良好的旧数据库项目和纯SQL,昨天刚刚开始。出于测试目的,我想在数据库中预先填充一组条目以进行测试。然而,这似乎并不像我预期的那样有效。我已经移动了一些东西,但错误信息不会消失:

无法添加实体类型“SourceColumnName”的种子实体 因为它设置了导航“SourceColumn”。播种 需要将相关实体种子添加到的关系 'SourceColumn'并指定外键值{'SourceColumnID'}。 考虑使用“dBraveTopStudioBuff.EnabelSythViDeAdTracle”到 请参见涉及的属性值

这是我的密码:

使用DE.ZA.MobilePickingApp.Models;
使用Microsoft.EntityFrameworkCore;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
运用系统反思;
命名空间DE.ZA.MobilePickingApp.Database{
公共类上下文:DbContext{
公共DbSet ViewerRoles{get;set;}
公共DbSet ViewerColumns{get;set;}
公共DbSet SourceColumns{get;set;}
配置时受保护的覆盖无效(DbContextOptionsBuilder选项){
options.UseSqlServer(“服务器=vWebDev01;数据库=MPA;集成安全性=True;”;
//选项。使用LazyLoadingProxies();
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder){
//=======数据种子设定=======
int columnCount=1;
List sourceColumns=新列表();
List SourceColumnNames=新列表();
List viewerColumns=新建列表();
//源列
foreach(typeof(PickingListEntry).GetProperties中的var prop(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)){
var col=new SourceColumn(){
ID=列数,
Key=prop.Name,
类型=(Nullable.GetUnderlineType(prop.PropertyType)??prop.PropertyType).Name
};
var colNaming=new SourceColumnNaming(){
SourceColumn=col,
Language=“de de”,
Text=MapPropertyName(prop.Name)
};
var viewerColumn=新的viewerColumn(){
ID=列数,
DataColumn=col,
IsEditable=false,
顺序=列数
};
sourceColumns.Add(col);
sourceColumnNamings.Add(colNaming);
viewerColumns.Add(viewerColumn);
columnCount++;
}
modelBuilder.Entity().HasData(SourceColumnNames);
modelBuilder.Entity().OwnsOne(sc=>sc.DefaultNames).HasData(sourceColumns);
modelBuilder.Entity().HasData(viewerColumns);
//观众角色
modelBuilder.Entity().HasData(
新的ViewerRole(){
ID=1,
Name=“Testrolle”,
Description=“这是一个测试卷”,
ViewerColumns=ViewerColumns
}
);
}
私有字符串MapPropertyName(字符串propName){
// ...
返回propName;
}
}
}
这就是我的数据对象的外观:

公共类源列{
[键,列(顺序=1)]
公共int ID{get;set;}
[必需]
公共字符串密钥{get;set;}
[必需]
公共字符串类型{get;set;}
[必需]
public List DefaultNames{get;set;}=new List();
}
公共类源列命名{
[关键]
public SourceColumn SourceColumn{get;set;}
[键,最大长度(5)]
公共字符串语言{get;set;}
公共字符串文本{get;set;}
}
公共类ViewerColumn{
[键,列(顺序=1)]
公共int ID{get;set;}
[必需]
公共虚拟源列数据列{get;set;}
公共字符串CustomName{get;set;}
公共整数顺序{get;set;}
公共bool可编辑{get;set;}
}
公共类视窗{
[键,列(顺序=1),JsonIgnore]
公共int ID{get;set;}
[必需]
公共字符串名称{get;set;}
公共字符串说明{get;set;}
[JsonIgnore]
public List ViewerColumns{get;set;}=new List();
[未映射]
public IEnumerable ClientColumns=>ViewerColumns?.Select(vc=>newmodels.clientColumn(){
Key=System.Text.Json.JsonNamingPolicy.CamelCase.ConvertName(vc.DataColumn.Key),
可排序=真
});
}

知道如何消除错误消息吗?

我在对数据库进行种子设定时使用它获得了巨大成功。它添加完整的“对象树”,使用现有外键,或者在数据库中找不到外键时添加它们

public void AddCascadingObject(object rootEntity) //Place inside DbContext.cs
{
    ChangeTracker.TrackGraph(
        rootEntity, 
        node => 
            node.Entry.State = !node.Entry.IsKeySet ? EntityState.Added : EntityState.Unchanged
    );
}   

我能解决这个问题。种子设定时,似乎不可能仅通过将数据项添加到彼此的导航属性来“自动绑定”数据项。相反,您不能设置导航属性,而是单独定义每个外键ID字段。为此,我必须首先将各种ID字段添加到数据模型中。此外,复合键不能通过添加两个
[Key]
注释(不再)来声明。因此,必须使用流体api

模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder){
InitializeKeys(modelBuilder);
种子数据(modelBuilder);
}
/// 
///初始化所有实体的复合键。
/// 
///方法的引用。
专用void初始化键(ModelBuilder ModelBuilder){
modelBuilder.Entity()
.HasKey(scn=>new{scn.SourceCo