I'm creating an Entity Framework 6 model using Code First Migrations, and I want a column in the resulting database to be fixed-length instead of variable-length; furthermore, I want to do this in a DBMS-agnostic way.
The ConventionPrimitivePropertyConfiguration.IsFixedLength method seemed built for this purpose. I couldn't find an existing attribute that used it, so I made one myself, like so:
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; }
}
However, when running Add-Migration using this code, the line that defines that database column in the resulting migration file (MyStringProperty = c.String(nullable: false, maxLength: 10)) doesn't say anything about fixed length. And when I run this migration on a database I get an NVARCHAR column.
What am I doing wrong here?
The StringLength attribute appears to be overwritting the FixedLength attribute. A workaround is to add the length property to your FixedLength attribute and set the HasMaxLength yourself
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; }
}
An to alternative to Aducci's answer is to use the ColumnAttribute to specify the datatype for the column:
class MyEntity
{
[Key]
[MaxLength(10)]
[Column(TypeName = "nchar")]
public string MyEntityId { get; set; }
}
This leads to column in the table:
MyEntityId nchar(10) NOT NULL PRIMARY KEY
Personally, I believe this method preferable, as it does not require overriding the DbContext's Apply function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With