![](/img/trans.png)
[英]Extracting the configuration created by DbContext.OnModelCreating in IDatabaseInitializer
[英]Emit DbContext.OnModelCreating on every context creation
我首先使用实体框架代码来处理我的数据库。 我有几个不同名称但结构相同的表,这些表动态地出现在数据库中。 我如何在运行时将EntityFramework映射到其中一个表并使用数据,就像我在DbContext的实体上工作一样?
我做了什么让它工作:
例如,我的类描述了动态创建的表的结构是SetElement
。
这是我的背景:
public class DataContext : DbContext
{
public DataContext()
: base("RepositoryConnectionString") { }
string setElementsTableId; // the name of table that need to be dynamicly mapped to
// Enforce model recreating
public DataContext(string setElementsTableId)
: this()
{
this.setElementsTableId = setElementsTableId;
}
/* some other entities */
public DbSet<Entities.SetElement> SetElements { get; set; } // dynamicly mapped entity
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
/* come configurations */
if (!string.IsNullOrEmpty(setElementsTableId))
{
modelBuilder.Entity<Entities.SetElement>().Map(x => x.ToTable(setElementsTableId)); // map SetElements property to dynamicly created table
}
}
}
我怎么用这个:
public static void AddSetElements(ICollection<SetElement> setElements, string tableId)
{
using (ctx = new DataContext(tableId)) // configere DataContext to map tableId table for entity SetElements
try
{
var num = ctx.SetElements.Count();
ctx.SetElements.AddRange(setElements);
ctx.SaveChanges();
}
catch (Exception e)
{
}
}
我还有一些方法来获取,udtate和从动态创建的表中删除与AddSetElements
相同的AddSetElements
。
所有工作都按照我的意愿工作,但只有当AddSetElements
首先运行时,因为在第一个datacontext创建DbContext.OnModelCreating
运行并配置所有映射。 但是下一个实例创建不会调用DbContext.OnModelCreating
。
所以,我的问题是:如何在每次创建DataContext
实例时调用DbContext.OnModelCreating
然后我使用DataContext(string setElementsTableId)
来创建它?
我知道,我的问题类似于'EF中的动态表映射',但我在结果中找不到任何内容。
顺便说说。 如果您知道解决问题的另一种方法,欢迎您。
有一个内置功能可以解决您的问题:`IDbModelCacheKey; 其实现将在您的配置中注册。 关键是为不同的上下文生成不同的密钥。
我会去做类似的事情:
一,配置
public class EntityFrameworkConfiguration: DbConfiguration
{
public EntityFrameworkConfiguration()
{
this.SetModelCacheKey(ctx => new EntityModelCacheKey((ctx.GetType().FullName + ctx.Database.Connection.ConnectionString).GetHashCode()));
}
}
然后执行IDbModelCacheKey
public class EntityModelCacheKey : IDbModelCacheKey
{
private readonly int _hashCode;
public EntityModelCacheKey(int hashCode)
{
_hashCode = hashCode;
}
public override bool Equals(object other)
{
if (other == null) return false;
return other.GetHashCode() == _hashCode;
}
public override int GetHashCode()
{
return _hashCode;
}
}
最后,您的DataContext
public class DataContext : DbContext
{
string setElementsTableId;
// use the setElementsTableId as extended property of the
// connection string to generate a custom key
public DataContext(string setElementsTableId)
: base(ConfigurationManager.ConnectionStrings["RepositoryConnectionString"]
+ "; Extended Properties=\"setElementsTableId=" + setElementsTableId + "\"")
{
this.setElementsTableId = setElementsTableId;
}
public DbSet<Entities.SetElement> SetElements { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
if (!string.IsNullOrEmpty(setElementsTableId))
{
modelBuilder.Entity<Entities.SetElement>().Map(x => x.ToTable(setElementsTableId));
}
}
}
我希望这会有所帮助
看起来没有人知道答案......
否则,一个人告诉我,我的问题没有意义,因为几个表中的存储数据不会给出任何成就。 更好地将索引添加到数据库,分区表或其他内容。 换句话说,这是数据库管理系统问题。 但如果有人知道答案,我会非常高兴听到有关EF黑客攻击的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.