问题描述
我首先使用实体框架代码来处理我的数据库.我有几个名称不同但结构相同的表,并且这些表动态出现在数据库中.我如何在运行时将 EntityFramework 映射到其中一个表并使用数据,就像我在 DbContext 的实体上工作一样?
I use entity framework code first to work with my database. I have several tables with different names but same structure, and this tables dynamically appears in database. How could I map EntityFramework to one of that tables at run-time and use data from just like I work this over entities of DbContext?
我为使它工作所做的工作:
What I've done to make it work:
例如,我的类描述动态创建表的结构是SetElement
.
For example, my class what describes structure of dynamically created table is 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)
{
}
}
我还有一些方法可以从与 AddSetElements
相同的动态创建的表中获取、更新和删除数据.
I have also some methods to get, udtate and remove data from dynamicly created tables that are same to AddSetElements
.
一切都如我所愿,但前提是 AddSetElements
首先运行,因为在第一个数据上下文创建 DbContext.OnModelCreating
运行并配置所有映射.但是下一个实例创建不会调用 DbContext.OnModelCreating
.
All works just as I wish but only if AddSetElements
runs first, because at the first datacontext creating DbContext.OnModelCreating
runs and configure all mappings. But next instance creation doesn't call DbContext.OnModelCreating
.
所以,我的问题是:如何在每次创建 DataContext
实例时调用 DbContext.OnModelCreating
然后我使用 DataContext(string setElementsTableId)
创建它?
So, my question is: how to call DbContext.OnModelCreating
everytime of creating an instance of DataContext
then I use DataContext(string setElementsTableId)
to create it?
我知道,我的问题类似于EF 中的动态表映射",但我在结果中一无所获.
I know, my question is similar to 'dynamic table mapping in EF' but I found nothing in the results.
顺便说一句.如果您知道另一种解决我的问题的方法,欢迎您.
By the way. If you know another way to solve my problem, you are welcome.
推荐答案
有一个内置功能可以解决您的问题:`IDbModelCacheKey;其实现将在您的配置中注册.关键是为您的不同上下文生成不同的密钥.
There is a built-in feature which may address your issue : `IDbModelCacheKey ; the implementation of which is to be registered in your configuration. The point is to generate a different key for your different contexts.
我会选择类似的东西:
一、配置
public class EntityFrameworkConfiguration: DbConfiguration
{
public EntityFrameworkConfiguration()
{
this.SetModelCacheKey(ctx => new EntityModelCacheKey((ctx.GetType().FullName + ctx.Database.Connection.ConnectionString).GetHashCode()));
}
}
然后是IDbModelCacheKey的实现
Then the implementation of the 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
Finally, your 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));
}
}
}
希望对你有所帮助
这篇关于在每次创建上下文时发出 DbContext.OnModelCreating的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!