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

问题描述 投票:0回答:1

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

例如:这就是正常情况

    [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; }
    }

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

c# attributes ado.net-entity-data-model
1个回答
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;
    }
}

接下来,您需要在Context的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还没有初始化..所以你必须要存储它在设置中或以其他方式传递它。

希望这可以帮助。

© www.soinside.com 2019 - 2024. All rights reserved.