我需要一个项目,以允许用户在配置文件中设置数据库信息和表名。我想使用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; }
}
任何帮助或让我知道这是不可能的,将不胜感激。
答案 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尚未初始化..因此,您必须将其存储在设置中或以其他方式传递。
希望这会有所帮助。