gpt4 book ai didi

c# - EF Core 2.1.0 设置默认字符串长度和列类型

转载 作者:太空狗 更新时间:2023-10-29 22:29:42 29 4
gpt4 key购买 nike

由于 Entity Framework 使用 nvarchar(max) 作为字符串的默认值,我想将其他内容设置为默认值。

https://dba.stackexchange.com/questions/48408/ef-code-first-uses-nvarcharmax-for-all-strings-will-this-hurt-query-performan

在 Entity Framework 6.1.3 中,我可以像这样修改 OnModelCreating(DbModelBuilder modelBuilder):

modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));
modelBuilder.Properties<DateTime>().Configure(c => c.HasPrecision(0));

modelBuilder.Properties<string>()
.Configure(s => s.HasMaxLength(256).HasColumnType("nvarchar"));

如果我随后修改了带有数据注释的属性,EF 将改为使用这些值,如下所示:

[MaxLength(128)]
public string Name { get; set; }

[Column(TypeName = "nvarchar(MAX)")]
[MaxLength]
public string Comment { get; set; }

但是使用 Microsoft.EntityFrameworkCore.SqlServer 2.1.0 我不能这样做,我也不能使用 Conventions

我可以像这样解决 datetime 但如果我尝试对字符串执行相同的操作,迁移会显示 type: "nvarchar(256)", maxLength: 128 如果我例如使用数据注释。我该如何解决这个问题?

foreach (var property in modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties())
.Where(p => p.ClrType == typeof(DateTime)))
{
property.Relational().ColumnType = "datetime2(0)";
}

最佳答案

更新(EF Core 6.0+):

EF Core 6.0 终于通过所谓的 Pre-convention model configuration 添加了指定不同类型映射默认值的功能。 ,所以现在的代码应该是这样的:

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
base.ConfigureConventions(configurationBuilder);

configurationBuilder.Properties<string>()
//.AreUnicode(false)
//.AreFixedLength()
.HaveMaxLength(256);
}

文档链接中提供了更多示例。

重要说明:但是,正如@PeterB 在评论中提到并在 EF Core 问题跟踪器中验证的那样,出于某种原因,此配置具有更高的优先级(与模型构建器流畅的 API 相同),因此您赢了能够使用数据注释覆盖这些“默认值”(OnModelCreating 中的流畅配置仍然可以)。因此,如果您依赖数据注释来覆盖默认值,您可能需要使用下面的原始方法。

原文:

有几个属性会间接影响 string 属性的列类型 - MaxLength(例如 varchar(256)varchar (MAX)IsUnicode(例如 nvarcharvarchar)和 IsFixedLength(例如 charvarchar)。

当前模型 API 不一致。第一个可通过 GetMaxLength 访问和 SetMaxLength , 第二个 - 通过 IsUnicodeIsUnicode ,第三个没有公共(public)模型 API(只有 Fluent API)。

因此,要设置 MaxLength,您可以使用:

foreach (var property in modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties())
.Where(p => p.ClrType == typeof(string)))
{
if (property.GetMaxLength() == null)
property.SetMaxLength(256);
}

这并不完全正确,因为在这种情况下 null 具有双重含义 - not specified 和 MAX

正确的方法需要使用 EF Core 内部 API,它提供了更多的配置方法,特别是允许您通过 ConfigurationSource枚举值以及属性值。 ConfigurationSource 枚举值定义配置的优先级 - Convention 最低,然后是 DataAnnotation,最后是 Explicit最高的。整个想法是较低优先级的配置不会覆盖较高优先级已经设置的配置。所有公共(public)的 Fluent API 都使用 Explcit,而在我们的例子中,Convention 非常适合(因为我们正在模拟传统的默认设置)。

因此,如果您接受警告“此 API 支持 Entity Framework Core 基础结构并且不打算直接在您的代码中使用。此 API 可能会在未来的版本中更改或删除。”,添加

using Microsoft.EntityFrameworkCore.Metadata.Internal;

和使用

foreach (var property in modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties())
.Where(p => p.ClrType == typeof(string)))
{
((Property)property).Builder
.HasMaxLength(256, ConfigurationSource.Convention);
}

关于c# - EF Core 2.1.0 设置默认字符串长度和列类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50840730/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com