在DbContext.OnModelCreating中读取各DbSet的自定义IdSeqAttribute
问题描述
我定义了如下IdSeqAttribute:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public class IdSeq(string seq) : Attribute { public string Seq = seq; }
并将其标注在约60个实体类上,示例如下:
[IdSeq("Customer")] public class Customer : MyModel { public string Nome { get; set; } = ""; } [IdSeq("Product")] public class Product : MyModel { public string Nome { get; set; } = ""; }
现在需要在DbContext的OnModelCreating方法中,为每个DbSet获取该属性,但通过entityType.GetAnnotations()无法找到IdSeqAttribute:
protected override void OnModelCreating(ModelBuilder modelBuilder) { foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { var annotatios = entityType.GetAnnotations(); // 此处可见两个属性,但未包含IdSeq } }
请问如何实现这一需求?
解决方案
entityType.GetAnnotations()获取的是EF Core模型层面的注解,而非类本身的.NET特性(Attribute)。要获取实体类上的IdSeqAttribute,需要从实体类型对应的CLR类型入手:
方法一:直接获取CLR类型的特性
在遍历entityType时,通过entityType.ClrType拿到对应的类类型,再用GetCustomAttribute方法获取特性:
protected override void OnModelCreating(ModelBuilder modelBuilder) { foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { // 获取实体类对应的CLR类型 var clrType = entityType.ClrType; // 获取IdSeqAttribute特性 var idSeqAttr = clrType.GetCustomAttribute<IdSeqAttribute>(); if (idSeqAttr != null) { // 拿到Seq值做后续处理 string seqValue = idSeqAttr.Seq; // 示例:执行自定义逻辑 // Console.WriteLine($"实体{clrType.Name}的Seq值为{seqValue}"); } } }
方法二:将特性导入EF Core注解(可选)
如果希望后续能通过entityType.GetAnnotations()访问该属性,可以先将实体类的IdSeqAttribute转化为EF Core的模型注解:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 先将IdSeqAttribute转化为EF Core注解 foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { var clrType = entityType.ClrType; var idSeqAttr = clrType.GetCustomAttribute<IdSeqAttribute>(); if (idSeqAttr != null) { // 添加自定义注解,键名可自定义 entityType.AddAnnotation("IdSeq", idSeqAttr.Seq); } } // 后续通过GetAnnotations()或FindAnnotation()获取 foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { var idSeqAnnotation = entityType.FindAnnotation("IdSeq"); if (idSeqAnnotation != null) { string seqValue = idSeqAnnotation.Value.ToString(); // 执行自定义逻辑 } } }
注意事项
- 确保
IdSeqAttribute的AttributeUsage配置正确(当前已指定AttributeTargets.Class,符合需求) - 当前
IdSeqAttribute设置了Inherited = false,不会从父类继承该特性;若需要继承特性,可改为Inherited = true
内容的提问来源于stack exchange,提问作者Rodolfo
相关产品推荐
相关产品推荐

