You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 07:30:54