skip to Main Content

1.I have a BaseModel class:

public class BaseModel : BaseDeletedModel
{
    [Key, Column(Order = 0), MaxLength(50), Required]
    public string ID { get; set; }
}


public class BaseDeletedModel
{
    [Column(Order = 100), DefaultValue(false)]
    public bool IsDeleted { get; set; }
}
  1. and then i create a bussiness class to inherit this base class:
public class Test: BaseModel
{
    [MaxLength(200), Required]
    public string Name { get; set; }
}

3.The script generated by the migration instruction is as follows:

columns: table => new
{
    id = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
    is_deleted = table.Column<bool>(type: "boolean", nullable: false, defaultValue: false),
   
    name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false)
}

4.but i want the order is:
id
name
isdeleted

I don’t want to use the Fluent API to set it up like this:

modelBuilder.Entity<Test>().Property(e => e.ID).HasColumnOrder(0);
modelBuilder.Entity<Test>().Property(e => e.Name).xxxxxxxxxx;
modelBuilder.Entity<Test>().Property(e => e.IsDeleted).HasColumnOrder(100).HasDefaultValue(false);

just set in entity class,is there a good solution?

2

Answers


  1. Chosen as BEST ANSWER

    @Svyatoslav Danyliv

    Thanks,Your solution has completely opened up my thinking。

    But there is a small issue, the method of entityType.GetProperties() is sorted alphabetically,so it cannot export like this : BName ,AName

    public class Test: BaseModel
    {
        public string BName { get; set; }
    
        public string AName { get; set; }
    }
    

    because the basemodel's fileds have Column(Order = x) x=0 (...) x=100 so i resolve it at the last like this:

    var columnOrder = property.GetColumnOrder();
    if (!columnOrder.HasValue)
    {
        property.SetColumnOrder(1);
    }
    

  2. You can define a custom extension method to sort properties in a specific order for all known entities:

    public static class ModelBuilderExtensions
    {
        public static ModelBuilder ApplyCustomColumnsOrder<TFirst, TLast>(this ModelBuilder modelBuilder)
        {
            var first = typeof(TFirst);
            var last = typeof(TLast);
    
            foreach (var entityType in modelBuilder.Model.GetEntityTypes())
            {
                if (!first.IsAssignableFrom(entityType.ClrType)) 
                    continue;
    
                var typeProperties = entityType.ClrType.GetProperties().ToList();
                var properties = entityType.GetProperties()
                    .Select((prop, index) => (
                        index: prop.PropertyInfo == null ? index * 10000 : typeProperties.IndexOf(prop.PropertyInfo),
                        prop))
                    .ToList();
    
                var sorted = properties
                    .OrderBy(p =>
                        p.prop.PropertyInfo?.DeclaringType == first ? 0 : p.prop?.PropertyInfo?.DeclaringType == last ? 2 : 1)
                    .ThenBy(p => p.index)
                    .Select(x => x.prop)
                    .ToList();
    
                for (var i = 0; i < sorted.Count; i++)
                {
                    sorted[i].SetColumnOrder(i);
                }
            }
    
            return modelBuilder;
        }
    }
    

    In the OnModelCreating method, you should call this extension method at the end of the method:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Other existing configurations
    
        modelBuilder.ApplyCustomColumnsOrder<BaseModel, BaseDeletedModel>();
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search