Situation:
I have a base class Lookup, as follows:
public abstract class Lookup : DeactivatableDomainModel {
[Required]
[Key]
public int ID { get; set; }
[Required]
public string Description { get; set; }
[Required]
public int DisplayOrder { get; set; }
}
I've also created an attribute IsLookup:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class IsLookup : Attribute {
public int DescriptionLength { get; set; }
public int CodeLength { get; set; }
public IsLookup(int DescriptionLength, int CodeLength = 0) {
this.DescriptionLength = DescriptionLength;
this.CodeLength = CodeLength;
}
}
The goal is to be able to create the following declaration:
[IsLookup(40)]
public class TestCategory : Lookup { }
...and use OnModelCreating
to set the MaxLength
of property Description to 40.
I've been able to code something that looks like it should work, and the add-migration
runs just fine, but the resulting migration doesn't have the maxlength set:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.Properties()
.Where(p => p.Name == "Description" && p.DeclaringType.GetCustomAttributes(false).OfType<IsLookup>().FirstOrDefault() != null)
.Configure(
c => c.HasMaxLength(((IsLookup)c.ClrPropertyInfo.DeclaringType.GetCustomAttributes(typeof(IsLookup), false).FirstOrDefault()).DescriptionLength)
);
}
The result is:
CreateTable(
"Lookups.TestCategories",
c => new {
ID = c.Int(nullable: false, identity: true),
Description = c.String(nullable: false),
DisplayOrder = c.Int(nullable: false),
Active = c.Boolean(nullable: false),
RowVersion = c.Binary(nullable: false, fixedLength: true, timestamp: true, storeType: "rowversion"),
})
.PrimaryKey(t => t.ID);
So, the question is...why doesn't Description have its length set in the migration code? Is this even possible?
<gripe>
If there was a way to debug add-migration
, this would be much easier.</gripe>
I am pretty sure that DeclaringType
will give you the type in which the property was declared, in your example the Lookup
class is where the Description
property is declared. Since Lookup
doesn't have the IsLookup
attribute, nothing gets set. Try looking through the registered types first then setting the Description column after you find it:
modelBuilder.Types()
.Where(t => t.IsSubclassOf(typeof(Lookup)))
.Having(x => x.GetCustomAttributes(false).OfType<IsLookup>().FirstOrDefault())
.Configure((config, att) => {
config.Property("Description").HasMaxLength(att.DescriptionLength);
});