Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF Core 5.0-如何使用列表为实体种子<;字符串>;迁移中的属性?_C#_Entity Framework Core - Fatal编程技术网

C# EF Core 5.0-如何使用列表为实体种子<;字符串>;迁移中的属性?

C# EF Core 5.0-如何使用列表为实体种子<;字符串>;迁移中的属性?,c#,entity-framework-core,C#,Entity Framework Core,我花了几个小时试图弄明白这一点,但可以找到解决办法 我有一个具有列表属性的实体,我想对其进行数据播种。我成功地使用了modelBuilder.Entity.HasData(),但它不适用于dotnet ef迁移 这是我的实体: 公共类MyEntity { 公共int Id{get;set;} 公共列表名称{get;set;} } 下面是我的DbContext.OnModelCreatingoverride: 模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder) {

我花了几个小时试图弄明白这一点,但可以找到解决办法

我有一个具有
列表
属性的实体,我想对其进行数据播种。我成功地使用了
modelBuilder.Entity.HasData()
,但它不适用于
dotnet ef迁移

这是我的实体:

公共类MyEntity
{
公共int Id{get;set;}
公共列表名称{get;set;}
}
下面是我的
DbContext.OnModelCreating
override:

模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasData(
新MyEntity{Id=1,Names=new List{“text1”,“text2”},
新的MyEntity{Id=2,Names=new List{“text1”,“text2”,“text3”},
新MyEntity{Id=3,Names=new List{“text1”,“text2”},
新的MyEntity{Id=4,Names=new List{“text1”,“text2”},
新的MyEntity{Id=5,name=new List{“text1”、“text2”、“text3”});
}
如果我运行我的应用程序,它会创建表并用想要的值为其种子。但是如果我运行
dotnet ef migrations add addmyenties--project src/MyProject--startup project src/MyProject.Api
,我会得到以下输出:

Build started...
Build succeeded.
System.NotSupportedException: The type mapping for 'List<string>' has not implemented code literal generation.
   at Microsoft.EntityFrameworkCore.Storage.CoreTypeMapping.GenerateCodeLiteral(Object value)
   at Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.UnknownLiteral(Object value)
   at Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.Literal(Object[,] values)
   at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationOperationGenerator.Generate(InsertDataOperation operation, IndentedStringBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationOperationGenerator.Generate(String builderName, IReadOnlyList`1 operations, IndentedStringBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGenerator.GenerateMigration(String migrationNamespace, String migrationName, IReadOnlyList`1 upOperations, IReadOnlyList`1 downOperations)
   at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType, String namespace)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
The type mapping for 'List<string>' has not implemented code literal generation.
已开始生成。。。
构建成功。
System.NotSupportedException:“List”的类型映射未实现代码文本生成。
位于Microsoft.EntityFrameworkCore.Storage.CoreTypeMapping.GenerateCollateral(对象值)
位于Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.UnknownLiteral(对象值)
位于Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.Literal(对象[,]值)
位于Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationOperationGenerator.Generate(InsertDataOperation操作,缩进StringBuilder)
位于Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationOperationGenerator.Generate(字符串生成器名称、IReadOnlyList`1操作、缩进字符串生成器)
位于Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationGenerator.GenerateMigrationMigrationMigrationName(字符串migrationNamespace、字符串migrationName、IReadOnlyList`1 upOperations、IReadOnlyList`1 downOperations)
位于Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(字符串迁移名称、字符串根命名空间、字符串子命名空间、字符串语言)
位于Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(字符串名称、字符串输出目录、字符串上下文类型、字符串命名空间)
位于Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(字符串名称、字符串输出目录、字符串上下文类型、字符串命名空间)
在Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.c__DisplayClass0_0.b_0()中
在Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.c__DisplayClass3_0`1.b__0()中
位于Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(操作)
“List”的类型映射尚未实现代码文本生成。
如何为简单的
列表
属性种子



编辑:我认为这个问题与其他问题不同,例如,如果我在空白数据库上启动程序,我的程序工作正常(使用PostgreSQL,它会创建一个
Names
列,类型为
text[]
,正如您所期望的那样)。问题是当我使用
dotnet ef
迁移工具时。

编辑:OP提到它正在与相应的ef提供程序一起使用PostgreSQL,因此问题不是缺少值转换器

这个问题似乎与EF核心本身的局限性有关。迁移脚手架过程目前使用一个内置的硬编码类,该类知道如何为一组封闭的类型生成C#literal。例如,它知道如何生成
对象[]
文本,但不知道如何生成
IEnumerable
。(参考文献:)。似乎现在提供者可以为其他类型的代码文本添加生成,我可以发现它是为中的某些类型添加的,但就我所了解的
List
而言,它不是为中的某些类型添加的。。。但我可能是错的,因为我自己没有测试过

我的建议?使用
string[]
或ditch
HasData
并提供一些自定义种子设定逻辑


OLD:问题不在于
HasData
功能本身。潜在的问题是EF Core本身不知道如何将
列表
存储到数据库中,因此它失败了

您可以做的是定义一个自定义的
ValueConverter
,它指示EF Core如何将特定属性存储到数据库列中(您可以查看此主题)

最好的方法可能是使用以下方法定义此转换:

模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.Property(p=>p.Names)
.哈斯转换(
listOfStringNames=>JsonConvert.SerializeObject(listOfStringNames),
namesJsonRepresentation=>JsonConvert.DeserializeObject(namesJsonRepresentation));
.HasData(
新MyEntity{Id=1,Names=new List{“text1”,“text2”},
新的MyEntity{Id=2,Names=new List{“text1”,“text2”,“text3”},
新MyEntity{Id=3,Names=new List{“text1”,“text2”},
新的MyEntity{Id=4,Names=new List{“text1”,“text2”},
新的MyEntity{Id=5,name=new List{“text1”、“text2”、“text3”});
}
作为旁注,我想提到的是,尽管
HasData
很好,但根据我的个人经验,最好只编写我自己的
DatabaseInitializer
类,该类将使用我想要的任何自定义逻辑为我需要的数据播种,而不使用任何
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyEntity>()
        .Property(p => p.Names)
        .HasConversion(
            listOfStringNames => JsonConvert.SerializeObject(listOfStringNames),
            namesJsonRepresentation => JsonConvert.DeserializeObject<List<string>>(namesJsonRepresentation));
        .HasData(
            new MyEntity { Id = 1, Names = new List<string> { "text1", "text2" } },
            new MyEntity { Id = 2, Names = new List<string> { "text1", "text2", "text3" } },
            new MyEntity { Id = 3, Names = new List<string> { "text1", "text2" } },
            new MyEntity { Id = 4, Names = new List<string> { "text1", "text2" } },
            new MyEntity { Id = 5, Names = new List<string> { "text1", "text2", "text3" } });
}