Reputation:
I'm building an EF6 code first model using the fluent API. My understanding is, by default, strings will be nvarchar(max)
, which (to be blunt) is dumb for a default. So I added the following convention code to set max default length to 255 characters:
modelBuilder.Properties<string>()
.Configure(p => p.HasMaxLength(255));
Then I created a decorator like so:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class TextAttribute : Attribute
{
}
I want to apply this to specific string properties that I actually want to be NVARCHAR(MAX)
.
What do I put in the fluent API to make sure all string properties with the [Text]
decorator are built in the database with NVARCHAR(MAX)
? I assume it would be something like this:
modelBuilder.Properties<string>()
.Where(p => p.CustomAttributes.Any(a => typeof(TextAttribute).IsAssignableFrom(a.AttributeType)))
.Configure(p => p.HasMaxLength(?????));
Or am I doing this completely wrong?
Upvotes: 27
Views: 29356
Reputation: 6781
If you use other database provider than MS SQL Server
then column type is possible to be other than NVARCHAR
and for this you need to use HasMaxLength
combine with IsUnicode
.
If you use:
builder.Property(e => e.ColumnName)
.HasColumnType("nvarchar(max)");
This is hard-coded for MS SQL Server
database provider and if you want to switch to other provider in time, you need to change all your entities configuration and also to change the migrations.
For example PostgreSql: PostgreSQL equivalent to SQL Server NVARCHAR (MAX) or Whats SQL Server NVARCHAR(max) equivalent in MySQL?
You can use for NVARCHAR(MAX)
:
builder.Property(e => e.ColumnName)
.HasMaxLength(int.MaxValue)
.IsUnicode(true);
You can use for VARCHAR(MAX)
:
builder.Property(e => e.ColumnName)
.HasMaxLength(int.MaxValue)
.IsUnicode(false);
Upvotes: 3
Reputation: 1809
It works for me in EF Core 7
entity.Property(e => e.ColumnName)
.HasMaxLength(int.MaxValue);
Upvotes: 2
Reputation: 775
You can use HasColumnType
or you can use without any HasColumnType or HasMaxLength. There is no need to use HasMaxLength
Upvotes: 3
Reputation: 139
There is a method to indicate that you use the maximum allowed by the database.
IsMaxLength ()
modelBuilder.Properties<string>()
.Where(p => p.CustomAttributes.Any(a => typeof(TextAttribute).IsAssignableFrom(a.AttributeType)))
.Configure(p => p.HasColumnType("nvarchar").IsMaxLength());
Upvotes: 8
Reputation: 6985
If you're doing it inside an EntityTypeConfiguration<MyEntity>
class, it is similar to @RickNo's answer, but is done like this:
Property(x => x.MyVarcharMaxProperty)
.HasColumnType("nvarchar(max)");
Upvotes: 18
Reputation: 423
I don't know if you've found an answer by now, but in case anyone else is wondering how to do it, simply set the SQL datatype and ignore the HasMaxLength() invocation.
modelBuilder.Properties<string>()
.Where(p => p.CustomAttributes.Any(a => typeof(TextAttribute).IsAssignableFrom(a.AttributeType)))
.Configure(p => p.HasColumnType("nvarchar(max)"));
Using IsMaxLength() or HasMaxLength(null) would set the field to nvarchar(4000) (varchar(8000) if specifying the data type as varchar).
Upvotes: 31