简体   繁体   中英

EF CodeFirst set default string length and override with DataAnnotations?

Most of my string columns I set around 50.

Rather than adding DataAnnotation [StringLength(50)] to every single string property, can I set the default string generation to 50, and only specify the DataAnnotation when I need it different to the default?

Eg

[StringLength(200)]
public string Thing1 { get; set; }
public string Thing2 { get; set; }
public string Thing3 { get; set; }
[MaxLength]
public string Thing4 { get; set; }

In this example, Thing2 and Thing3 could be varchar(50) by default, and Thing1 and Thing2 would differ since I've specifically set them otherwise

Many entities and columns so this would not only save me time, but make my entity classes look much cleaner

To clarify (for the sake of possible duplicate questions): - I don't mind how the default length is set (FluentAPI or anything else) - I do mind how the override length is set. I want to override using DataAnnotations

You can use a custom code first convention. Try to add this to your context class:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Properties<string>() 
                .Configure(c => c.HasMaxLength(500));
}

Check this link for more information about Custom Code First Conventions

Yes, 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.

/// <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 MyDbContext : DbContext
{
    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; }
}

Since Entity Frameworks Core 6, now you can override ConfigureConventions DbContext setting the default configuration for a given property Type according to this site

Example:

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
  {
     // Pre-convention model configuration goes here
     configurationBuilder.Properties<string>().HaveMaxLength(300);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM