Ogg*_*las 5 c# entity-framework entity-framework-core
由于Entity Framework将nvarchar(max)
字符串默认用作默认值,因此我想将其他内容设置为默认值。
在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"));
Run Code Online (Sandbox Code Playgroud)
如果随后我使用数据注释修改了属性,EF则改用这些值,如下所示:
[MaxLength(128)]
public string Name { get; set; }
[Column(TypeName = "nvarchar(MAX)")]
[MaxLength]
public string Comment { get; set; }
Run Code Online (Sandbox Code Playgroud)
但是使用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)";
}
Run Code Online (Sandbox Code Playgroud)
有几个属性会间接影响属性的列类型string
- MaxLength
(例如varchar(256)
vs varchar(MAX)
,IsUnicode
(例如nvarchar
vs varchar
)和IsFixedLength
(例如char
vs varchar
)。
当前的模型API不一致。第一种是通过访问GetMaxLength
和SetMaxLength
,第二个-通过IsUnicode
和IsUnicode
,并没有为第三个(仅流畅API)没有公共模型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);
}
Run Code Online (Sandbox Code Playgroud)
这并不完全正确,因为null
在这种情况下具有双重含义-未指定和MAX
。
正确的方法需要使用EF Core内部API,该API提供了更多的配置方法,尤其是允许您将ConfigurationSource
枚举值与属性值一起传递。ConfigurationSource
枚举值定义配置的优先级- Convention
最低,然后DataAnnotation
最后Explicit
是最高。整个想法是,较低优先级的配置不会覆盖已经由较高优先级设置的配置。所有公共语言API都使用Explcit
,而在我们的情况下则Convention
非常适合(因为我们正在模拟常规默认值)。
因此,如果您接受警告“此API支持Entity Framework Core基础结构,并且不能直接在您的代码中使用。此API可能会更改或在将来的版本中删除。” ,添加
using Microsoft.EntityFrameworkCore.Metadata.Internal;
Run Code Online (Sandbox Code Playgroud)
和使用
foreach (var property in modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties())
.Where(p => p.ClrType == typeof(string)))
{
property.AsProperty().Builder
.HasMaxLength(256, ConfigurationSource.Convention);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4100 次 |
最近记录: |