Brian
Brian

Reputation: 131

Configure modelBuilder to combine more than one property configuration at a time

Is there a way that I can combine more than one property for Required, MaxLength and HasColumn or do I need to create one for each property?

I would like to be able to include multiple fields to be required along with assisgning them the same MaxLength if they are instead of creating a new one for each field in the entity like I'm doing below now.

public class DataEntryContext : DbContext
{
    public DataEntryContext(DbContextOptions<DataEntryContext> options)
        :base (options)
    { }

    public DbSet<Employee> Employees { get; set; }
    public DbSet<Department> Departments { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Employee>()
            .HasKey(e => e.EmpId);

        modelBuilder.Entity<Employee>()
            .Property(e => e.EmpFirstName)
            .HasColumnType("varchar(50)")
            .HasMaxLength(50)
            .IsRequired();

        modelBuilder.Entity<Employee>()
            .Property(e => e.EmpLastName)
            .HasColumnType("varchar(50)")
            .HasMaxLength(50)
            .IsRequired();

        modelBuilder.Entity<Employee>()
            .Property(e => e.EmpPhoneNumber)
            .HasColumnType("varchar(10)")
            .HasMaxLength(10)
            .IsRequired();

        modelBuilder.Entity<Employee>()
            .Property(e => e.EmpStartDate)
            .HasColumnType("datetime")
            .IsRequired();


        modelBuilder.Entity<Department>()
            .HasKey(d => d.DeptId);

        modelBuilder.Entity<Department>()
            .Property(d => d.DeptName)
            .HasColumnType("varchar(50)")
            .HasMaxLength(50)
            .IsRequired();

    }
}

Upvotes: 3

Views: 3285

Answers (2)

Erik Philips
Erik Philips

Reputation: 54638

Sure you can, you just have to write the code yourself. For example, I wrote a EntityTypeConfigurationExtensions that allows you to configure a entity with multiple properties in a single call instead of multiple calls. I don't see why you couldn't modify my code to use params and then you could pass multiple properties:

(you'd have to make the propertyConfiguration come first, then the propertyExpression)

public static class EntityTypeConfigurationExtensions
{
    public static EntityTypeConfiguration<TEntityType> Property<TEntityType>(
        this EntityTypeConfiguration<TEntityType> instance,
        Expression<Func<TEntityType, byte[]>> propertyExpression,
        Func<BinaryPropertyConfiguration, BinaryPropertyConfiguration> propertyConfiguration)
        where TEntityType : class
    {
        propertyConfiguration(instance.Property(propertyExpression));

        return instance;
    }

    public static EntityTypeConfiguration<TEntityType> Property<TEntityType>(
        this EntityTypeConfiguration<TEntityType> instance,
        Expression<Func<TEntityType, Guid>> propertyExpression,
        Func<PrimitivePropertyConfiguration, PrimitivePropertyConfiguration> propertyConfiguration)
        where TEntityType : class
    {
        propertyConfiguration(instance.Property(propertyExpression));

        return instance;
    }

    public static EntityTypeConfiguration<TEntityType> Property<TEntityType>(
        this EntityTypeConfiguration<TEntityType> instance,
        Expression<Func<TEntityType, Guid?>> propertyExpression,
        Func<PrimitivePropertyConfiguration, PrimitivePropertyConfiguration> propertyConfiguration)
        where TEntityType : class
    {
        propertyConfiguration(instance.Property(propertyExpression));

        return instance;
    }

    public static EntityTypeConfiguration<TEntityType> Property<TEntityType>(
        this EntityTypeConfiguration<TEntityType> instance,
        Expression<Func<TEntityType, TimeSpan?>> propertyExpression,
        Func<DateTimePropertyConfiguration, DateTimePropertyConfiguration> propertyConfiguration)
        where TEntityType : class
    {
        propertyConfiguration(instance.Property(propertyExpression));

        return instance;
    }

    public static EntityTypeConfiguration<TEntityType> Property<TEntityType>(
        this EntityTypeConfiguration<TEntityType> instance,
        Expression<Func<TEntityType, TimeSpan>> propertyExpression,
        Func<DateTimePropertyConfiguration, DateTimePropertyConfiguration> propertyConfiguration)
        where TEntityType : class
    {
        propertyConfiguration(instance.Property(propertyExpression));

        return instance;
    }

    public static EntityTypeConfiguration<TEntityType> Property<TEntityType>(
        this EntityTypeConfiguration<TEntityType> instance,
        Expression<Func<TEntityType, DateTimeOffset?>> propertyExpression,
        Func<DateTimePropertyConfiguration, DateTimePropertyConfiguration> propertyConfiguration)
        where TEntityType : class
    {
        propertyConfiguration(instance.Property(propertyExpression));

        return instance;
    }

    public static EntityTypeConfiguration<TEntityType> Property<TEntityType>(
        this EntityTypeConfiguration<TEntityType> instance,
        Expression<Func<TEntityType, DateTimeOffset>> propertyExpression,
        Func<DateTimePropertyConfiguration, DateTimePropertyConfiguration> propertyConfiguration)
        where TEntityType : class
    {
        propertyConfiguration(instance.Property(propertyExpression));

        return instance;
    }

    public static EntityTypeConfiguration<TEntityType> Property<TEntityType>(
        this EntityTypeConfiguration<TEntityType> instance,
        Expression<Func<TEntityType, DateTime?>> propertyExpression,
        Func<DateTimePropertyConfiguration, DateTimePropertyConfiguration> propertyConfiguration)
        where TEntityType : class
    {
        propertyConfiguration(instance.Property(propertyExpression));

        return instance;
    }

    public static EntityTypeConfiguration<TEntityType> Property<TEntityType>(
        this EntityTypeConfiguration<TEntityType> instance,
        Expression<Func<TEntityType, DateTime>> propertyExpression,
        Func<DateTimePropertyConfiguration, DateTimePropertyConfiguration> propertyConfiguration)
        where TEntityType : class
    {
        propertyConfiguration(instance.Property(propertyExpression));

        return instance;
    }

    public static EntityTypeConfiguration<TEntityType> Property<TEntityType>(
        this EntityTypeConfiguration<TEntityType> instance,
        Expression<Func<TEntityType, decimal?>> propertyExpression,
        Func<DecimalPropertyConfiguration, DecimalPropertyConfiguration> propertyConfiguration)
        where TEntityType : class
    {
        propertyConfiguration(instance.Property(propertyExpression));

        return instance;
    }

    public static EntityTypeConfiguration<TEntityType> Property<TEntityType>(
        this EntityTypeConfiguration<TEntityType> instance,
        Expression<Func<TEntityType, decimal>> propertyExpression,
        Func<DecimalPropertyConfiguration, DecimalPropertyConfiguration> propertyConfiguration)
        where TEntityType : class
    {
        propertyConfiguration(instance.Property(propertyExpression));

        return instance;
    }

    public static EntityTypeConfiguration<TEntityType> Property<TEntityType>(
        this EntityTypeConfiguration<TEntityType> instance,
        Expression<Func<TEntityType, string>> propertyExpression,
        Func<StringPropertyConfiguration, StringPropertyConfiguration> propertyConfiguration)
        where TEntityType : class
    {
        propertyConfiguration(instance.Property(propertyExpression));

        return instance;
    }
}

Now this:

modelBuilder.Entity<Employee>()
  .HasKey(e => e.EmpId);

modelBuilder.Entity<Employee>()
  .Property(e => e.EmpFirstName)
  .HasColumnType("varchar(50)")
  .HasMaxLength(50)
  .IsRequired();

modelBuilder.Entity<Employee>()
  .Property(e => e.EmpLastName)
  .HasColumnType("varchar(50)")
  .HasMaxLength(50)
  .IsRequired();

modelBuilder.Entity<Employee>()
  .Property(e => e.EmpStartDate)
  .HasColumnType("datetime")
  .IsRequired();

Is now:

modelBuilder.Entity<Employee>()
  .HasKey(e => e.EmpId)
  .Property(e => e.EmpFirstName,
    p => p.HasColumnType("varchar(50)")
     .HasMaxLength(50)
     .IsRequired())
  .Property(e => e.EmpLastName,
    p => p.HasColumnType("varchar(50)")
      .HasMaxLength(50)
      .IsRequired())
  .Property(e => e.EmpStartDate,
    p => p.HasColumnType("datetime")
      .IsRequired());

So modiying my code to use params and updating the plumping to just loop through the params would yeild:

modelBuilder.Entity<Employee>()
  .HasKey(e => e.EmpId)
  .Property(p => p.HasColumnType("varchar(50)")
    .HasMaxLength(50)
    .IsRequired(),
    e => e.EmpFirstName,
    e => e.EmpLastName);
  .Property(p => p.HasColumnType("datetime")
    .IsRequired(),
    e => e.EmpStartDate,);

Upvotes: 1

Ankit
Ankit

Reputation: 2518

No that's not possible as of now. You have to write that for each property. At max you can coerce Entity Framework to map a .Net data type to a particular MS SQL data-type as shown here.

Upvotes: 0

Related Questions