在每次创建上下文时发出 DbContext.OnModelCreating
Emit DbContext.OnModelCreating on every context creation
我首先使用 entity framework 代码来处理我的数据库。
我有几个名称不同但结构相同的 table,并且这个 table 动态出现在数据库中。我如何在 运行 时将 EntityFramework 映射到其中一个 table 并使用来自 DbContext 实体的数据?
我为让它发挥作用所做的工作:
比如我的class描述动态创建的table的结构是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)
{
}
}
我还有一些方法可以从动态创建的 table 中获取、更新和删除数据,这些方法与 AddSetElements
.
相同
一切都按照我的意愿工作,但前提是先 AddSetElements
运行s,因为在第一个数据上下文中创建 DbContext.OnModelCreating
运行s 并配置所有映射。但是下一个实例创建不会调用 DbContext.OnModelCreating
.
所以,我的问题是:每次创建 DataContext
的实例时如何调用 DbContext.OnModelCreating
然后我使用 DataContext(string setElementsTableId)
创建它?
我知道,我的问题类似于'dynamic table mapping in EF',但我在结果中没有找到。
顺便说一句。如果你知道另一种方法来解决我的问题,欢迎你。
好像没人知道答案...
否则,一个人告诉我,我的问题是没有意义的,因为存储数 tables 中的数据不会给出任何成就。更好地向数据库添加索引,分区 table 或其他东西。换句话说,这是数据库管理系统问题。但是,如果有人知道答案,我会很高兴听到有关 EF hack 的消息。
有一个内置功能可以解决您的问题:`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));
}
}
}
希望对您有所帮助
我首先使用 entity framework 代码来处理我的数据库。 我有几个名称不同但结构相同的 table,并且这个 table 动态出现在数据库中。我如何在 运行 时将 EntityFramework 映射到其中一个 table 并使用来自 DbContext 实体的数据?
我为让它发挥作用所做的工作:
比如我的class描述动态创建的table的结构是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)
{
}
}
我还有一些方法可以从动态创建的 table 中获取、更新和删除数据,这些方法与 AddSetElements
.
一切都按照我的意愿工作,但前提是先 AddSetElements
运行s,因为在第一个数据上下文中创建 DbContext.OnModelCreating
运行s 并配置所有映射。但是下一个实例创建不会调用 DbContext.OnModelCreating
.
所以,我的问题是:每次创建 DataContext
的实例时如何调用 DbContext.OnModelCreating
然后我使用 DataContext(string setElementsTableId)
创建它?
我知道,我的问题类似于'dynamic table mapping in EF',但我在结果中没有找到。
顺便说一句。如果你知道另一种方法来解决我的问题,欢迎你。
好像没人知道答案...
否则,一个人告诉我,我的问题是没有意义的,因为存储数 tables 中的数据不会给出任何成就。更好地向数据库添加索引,分区 table 或其他东西。换句话说,这是数据库管理系统问题。但是,如果有人知道答案,我会很高兴听到有关 EF hack 的消息。
有一个内置功能可以解决您的问题:`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));
}
}
}
希望对您有所帮助