我需要一个允许用户在配置文件中设置数据库信息和表名的项目。我想使用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; }
}
任何帮助或让我知道它是不可能的将不胜感激。
我没有对此进行测试,但我认为你可以通过实现自定义约定来实现这一点 - 如果你至少使用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还没有初始化..所以你必须要存储它在设置中或以其他方式传递它。
希望这可以帮助。