发出DbContext.OnModelCreating每个上下文创建 [英] Emit DbContext.OnModelCreating on every context creation

查看:3590
本文介绍了发出DbContext.OnModelCreating每个上下文创建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用实体框架代码先用我的数据库工作。
我有不同的名称,但相同的结构几个表,这表动态出现在数据库中。我怎么会在运行时和使用数据映射的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?

我所做的使它的工作:

例如,我的课有什么介绍了动态创建的表的结构是 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)
       {
       }
 }

我也有一些方法来获得,udtate并从动态地创建的表是一样的,以 AddSetElements 数据。

I have also some methods to get, udtate and remove data from dynamicly created tables that are same to AddSetElements.

所有作品一样祝但只有当 AddSetElements 先运行,因为在第一次的datacontext创建 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.

所以,我的问题是:如何调用 DbContext.OnModelCreating 创建的DataContext 然后使用的DataContext(字符串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)); 
    }
  }
}



我希望这将是一些帮助

I hope this will be of some help

这篇关于发出DbContext.OnModelCreating每个上下文创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆