代码优先迁移中的固定长度字符串列

本文关键字:字符串 迁移 代码 | 更新日期: 2023-09-27 18:08:40

我正在使用代码优先迁移创建实体框架6模型,我希望结果数据库中的列是固定长度而不是可变长度;此外,我想以一种与dbms无关的方式来实现这一点。

ConventionPrimitivePropertyConfiguration。IsFixedLength方法似乎就是为此目的而构建的。我找不到使用它的现有属性,所以我自己创建了一个,如下所示:

using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Configuration;
using System.Data.Entity.ModelConfiguration.Conventions;
class FixedLengthAttribute : Attribute { }
class FixedLengthAttributeConvention
    : PrimitivePropertyAttributeConfigurationConvention<FixedLengthAttribute>
{
    public override void Apply(ConventionPrimitivePropertyConfiguration configuration,
        FixedLengthAttribute attribute)
    {
        configuration.IsFixedLength();
    }
}
class MyModel : DbContext
{
    internal virtual DbSet<MyEntity> MyEntities { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Add(new FixedLengthAttributeConvention());
    }
}
class MyEntity
{
    [Key, FixedLength, StringLength(10)]
    public string MyStringProperty { get; set; }
}

然而,当使用这段代码运行Add-Migration时,在生成的迁移文件(MyStringProperty = c.String(nullable: false, maxLength: 10))中定义该数据库列的那行并没有说任何关于固定长度的内容。当我在数据库上运行这个迁移时,我得到一个NVARCHAR列。

我在这里做错了什么?

代码优先迁移中的固定长度字符串列

StringLength属性似乎覆盖了FixedLength属性。一个解决方法是将长度属性添加到FixedLength属性中,并自己设置HasMaxLength

class FixedLengthAttribute : Attribute 
{ 
    public int Length { get; set; }
}

public override void Apply(ConventionPrimitivePropertyConfiguration configuration,
        FixedLengthAttribute attribute)
{
    configuration.IsFixedLength();
    configuration.HasMaxLength(attribute.Length);
}
class MyEntity
{
    [Key, FixedLength(Length=10)]
    public string MyStringProperty { get; set; }
}

Aducci的答案的另一种替代方法是使用ColumnAttribute指定列的数据类型:

class MyEntity
{
    [Key]
    [MaxLength(10)]
    [Column(TypeName = "nchar")]
    public string MyEntityId { get; set; }
}

这导致表中的列:

MyEntityId nchar(10) NOT NULL PRIMARY KEY

我个人认为这种方法更可取,因为它不需要重写DbContextApply函数。