Darren Wainwright
Darren Wainwright

Reputation: 30727

Setting MaxLength for all strings in Entity Framework code first

I'm developing a code-first database, using Entity Framework 6.

I know I can set [MaxLength(myLen)] on the property of a model.

What I wondered, is if this is possible to do in a filter or a custom attribute, so that all strings take on a default, of say 250, unless specified directly on the property.

Failing this, is there a way to change the default of nvarchar(max)?

Upvotes: 5

Views: 13258

Answers (4)

sajadre
sajadre

Reputation: 1181

In this code ModelBuilder class defines the shape of your entities, the relationships between them, and how they map to the database.

public class WebsiteDBContext : DbContext
{

    public WebsiteDBContext(DbContextOptions<WebsiteDBContext> options) : base(options)
    {
    }

    public DbSet<Global> Globals { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        // it should be placed here, otherwise it will rewrite the following settings!
        base.OnModelCreating(builder);

        builder.Entity<Global>();
        builder.Entity<Global>(entity =>
        {
            entity.Property(global => global.MainTopic).HasMaxLength(150).IsRequired();
            entity.Property(global => global.SubTopic).HasMaxLength(300).IsRequired(false);
            entity.Property(global => global.Subject).IsRequired(false);
            entity.Property(global => global.URL).HasMaxLength(150).IsRequired(false);
        });
    }

}

Upvotes: 1

Sergei Zinovyev
Sergei Zinovyev

Reputation: 1286

In EF6 you can use a custom code first convention, but you will also need to have a way to specify nvarchar(max) data type to a string property. So, I came up with the following solution. Also see: https://msdn.microsoft.com/en-us/data/jj819164#order

/// <summary>
/// Set this attribute to string property to have nvarchar(max) type for db table column.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class TextAttribute : Attribute
{
}

/// <summary>
/// Changes all string properties without System.ComponentModel.DataAnnotations.StringLength or
/// Text attributes to use string length 16 (i.e nvarchar(16) instead of nvarchar(max) by default).
/// Use TextAttribute to a property to have nvarchar(max) data type.
/// </summary>
public class StringLength16Convention : Convention
{
    public StringLength16Convention()
    {
        Properties<string>()
            .Where(p => !p.GetCustomAttributes(false).OfType<DatabaseGeneratedAttribute>().Any())
            .Configure(p => p.HasMaxLength(16));

        Properties()
            .Where(p => p.GetCustomAttributes(false).OfType<TextAttribute>().Any())
            .Configure(p => p.IsMaxLength());
    }
}

public class CoreContext : DbContext, ICoreContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //Change string length default behavior.
        modelBuilder.Conventions.Add(new StringLength16Convention());
    }
}


public class LogMessage
{
    [Key]
    public Guid Id { get; set; }


    [StringLength(25)] // Explicit data length. Result data type is nvarchar(25)
    public string Computer { get; set; }

    //[StringLength(25)] // Implicit data length. Result data type is nvarchar(16)
    public string AgencyName { get; set; }

    [Text] // Explicit max data length. Result data type is nvarchar(max)
    public string Message { get; set; }
}

Upvotes: 1

Colin
Colin

Reputation: 22595

Entity Framework introduced Custom Code First Conventions for this in 6.1

modelBuilder.Properties<string>()
            .Configure(c => c.HasMaxLength(250));

Conventions operate in a last wins manner and the Fluent API and Data Annotations can be used to override a convention in specific cases

Upvotes: 10

greg84
greg84

Reputation: 7609

You can do this, which ensures all strings are the maximum length supported by the database provider:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Properties<string>().Configure(p => p.IsMaxLength());
    }

Add this method (or modify the existing one) in your DbContext class.

Upvotes: 8

Related Questions