EF6 根据包含 class 的属性设置 属性 的 MaxLength
EF6 Set MaxLength of a property based on attribute of the containing class
情况:
我有一个baseclassLookup,如下:
public abstract class Lookup : DeactivatableDomainModel {
[Required]
[Key]
public int ID { get; set; }
[Required]
public string Description { get; set; }
[Required]
public int DisplayOrder { get; set; }
}
我还创建了一个属性 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;
}
}
目标是能够创建以下声明:
[IsLookup(40)]
public class TestCategory : Lookup { }
...并使用 OnModelCreating
将 属性 描述的 MaxLength
设置为 40。
我已经能够编写一些看起来应该可以工作的代码,并且 add-migration
运行得很好,但是生成的迁移没有设置最大长度:
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)
);
}
结果是:
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);
所以,问题是...为什么 Description 没有在迁移代码中设置其长度?这可能吗?
<gripe>
如果有调试的方法add-migration
,那就简单多了。</gripe>
我很确定 DeclaringType
会给你声明 属性 的类型,在你的例子中 Lookup
class 是 Description
属性 被声明。由于 Lookup
没有 IsLookup
属性,因此不会设置任何内容。尝试先查看已注册的类型,然后在找到后设置描述列:
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);
});
情况:
我有一个baseclassLookup,如下:
public abstract class Lookup : DeactivatableDomainModel {
[Required]
[Key]
public int ID { get; set; }
[Required]
public string Description { get; set; }
[Required]
public int DisplayOrder { get; set; }
}
我还创建了一个属性 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;
}
}
目标是能够创建以下声明:
[IsLookup(40)]
public class TestCategory : Lookup { }
...并使用 OnModelCreating
将 属性 描述的 MaxLength
设置为 40。
我已经能够编写一些看起来应该可以工作的代码,并且 add-migration
运行得很好,但是生成的迁移没有设置最大长度:
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)
);
}
结果是:
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);
所以,问题是...为什么 Description 没有在迁移代码中设置其长度?这可能吗?
<gripe>
如果有调试的方法add-migration
,那就简单多了。</gripe>
我很确定 DeclaringType
会给你声明 属性 的类型,在你的例子中 Lookup
class 是 Description
属性 被声明。由于 Lookup
没有 IsLookup
属性,因此不会设置任何内容。尝试先查看已注册的类型,然后在找到后设置描述列:
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);
});