ADO.NET实体模型-动态分配TableAttribute

时间:2019-03-02 21:32:52

标签: c# attributes ado.net-entity-data-model

我需要一个项目,以允许用户在配置文件中设置数据库信息和表名。我想使用ADO.NET实体模型来使用LINQ,并尽我最大可能远离SQL,以使其对我自己更容易。有没有一种方法可以动态地分配Class需要为模态访问的表?

例如: 这是正常的样子

    [Table("database.table")]
    public partial class table
    {
        [Key]
        [Column(TypeName = "usmallint")]
        public int ID { get; set; }

        [Required]
        [StringLength(128)]
        public string Instance { get; set; }

        [Required]
        [StringLength(60)]
        public string Name { get; set; }
    }

我希望能够动态设置TableAttribute,以便模型知道要访问该类的表。

    [Table(Config.DBName + Config.tableName)]
    public partial class table
    {
        [Key]
        [Column(TypeName = "usmallint")]
        public int ID { get; set; }

        [Required]
        [StringLength(128)]
        public string Instance { get; set; }

        [Required]
        [StringLength(60)]
        public string Name { get; set; }
    }

任何帮助或让我知道这是不可能的,将不胜感激。

1 个答案:

答案 0 :(得分:0)

我还没有测试过,但是我认为,如果您至少使用EF6,则可以通过实现自定义的约定来做到这一点。

首先,您需要创建一个自定义约定:

public class CustomTableNameConvention : IStoreModelConvention<EntitySet>
{
    private readonly string _tablePrefix;

    public CustomTableNameConvention(string tablePrefix)
    {
        _tablePrefix = tablePrefix;
    }

    public void Apply(EntitySet item, DbModel model)
    {
        //change table name.
        item.Table = $"{_tablePrefix}" + item.Table;
    }
}

接下来,您需要在上下文的OnModelCreating方法中添加以下约定:

public class MyContext : DbContext
{
    public MyContext(string connectionString) : base(connectionstring)
    {
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //get the dynamic table prefix...
        var myAppPrefix = "user1";
        modelBuilder.Conventions.Add(new CustomTableNameConvention(myAppPrefix));
        base.OnModelCreating(modelBuilder);
    }

    public DbSet<SomeModel> { get; set; }
    ...
}

...然后,每当启动此应用程序实例中的模型 时,在决定表名应为哪种时,都应运行上述过程。 只需将myAppPrefix = ...代码替换为对适当服务的调用即可获取该实例的前缀。

一个明显的警告是,您不能使用从数据库返回的前缀的值(至少不是通过此Context),因为Context尚未初始化..因此,您必须将其存储在设置中或以其他方式传递。

希望这会有所帮助。