如何动态地将实体框架模型映射到表名 [英] How to map an Entity framework model to a table name dynamically
问题描述
使用代码优先的方法,我想将单个模型映射到多个表名称动态。目前,我可以像 modelBuilder.Entity(Of Person)()。MapSingleType()。ToTable(Managers)
,但作为 OnModelCreating
方法只有在我无法将其映射到其他表名时才会被调用。
在我们当前的LinqToSql版本中,我们将覆盖MetaModel.GetTable(),并返回一个新的TableAttribute与我们的动态名称。我没有在EF中找到这样的属性(即使我不知道如何覆盖它)。所以我的问题是:是否可以这样做?(/)
更新
我发现我可以通过调用
阻止 OnModelCreating
方法缓存映射modelBuilder.CacheForContextType = false;
因此,我可以为对象的实例分配表定义。这不是我想做的,但它是有效的。
更新
哦,男孩,是以上一个大错误...缓存存在一个原因! :)所以我回到方块一个与POCO对象映射。我会发布一个更新,如果我找出一个解决方案。
最终
任何人都关心我' ve目前解决了这个问题,在这里你去:
首先我创建了一个单独的库与POCO表和一个接口
public interface IDataContext {
System.Data.Entity.DbSet< TableGeneric> TableGeneric {get;组; }
int SaveChanges();
}
public class TableGeneric {
[Key]
public int Column1 {get;组; }
public string Column2 {get;组; }
public DateTime Column3 {get;组; }
public string Column4 {get;组; }
public string Column5 {get;组; }
}
然后,使用CSharpCodeProvider创建了一个类,它接受以下模板和将其转换为类型定义:
class DataContext:System.Data.Entity.DbContext,IDataContext {
public System .Data.Entity.DbSet< TableGeneric> TableGeneric {get;组; }
protected override void OnModelCreating(ModelBuilder modelBuilder){
modelBuilder
.Entity< ContextTesting.Interfaces.EF.TableGeneric()
.MapSingleType()
.ToTable($ TableName $);
}
}
使用生成的类型,我可以创建一个实例,所以这里我们去
类型typeAccountants = BuildContext.CreateGenericTable(Accountants);
IDataContext context =(IDataContext)Activator.CreateInstance(typeAccountants);
其余的就好像你有一个普通的DataContext。希望这有助于别人。
任何人都关心我目前如何解决这个问题,在这里你去:
首先,我创建了一个单独的库与POCO表和一个接口
public接口IDataContext {
System.Data.Entity.DbSet< TableGeneric> TableGeneric {get;组; }
int SaveChanges();
}
public class TableGeneric {
[Key]
public int Column1 {get;组; }
public string Column2 {get;组; }
public DateTime Column3 {get;组; }
public string Column4 {get;组; }
public string Column5 {get;组; }
}
然后,使用CSharpCodeProvider创建了一个类,它接受以下模板和将其转换为类型定义:
class DataContext:System.Data.Entity.DbContext,IDataContext {
public System .Data.Entity.DbSet< TableGeneric> TableGeneric {get;组; }
protected override void OnModelCreating(ModelBuilder modelBuilder){
modelBuilder
.Entity< ContextTesting.Interfaces.EF.TableGeneric()
.MapSingleType()
.ToTable($ TableName $);
}
}
使用生成的类型,我可以创建一个实例,所以这里我们去
类型typeAccountants = BuildContext.CreateGenericTable(Accountants);
IDataContext context =(IDataContext)Activator.CreateInstance(typeAccountants);
其余的就好像你有一个普通的DataContext。希望这有助于别人。
Using a code-first approach I'd like to map a single model to multiple table names dynamically. Currently I can do something like modelBuilder.Entity(Of Person)().MapSingleType().ToTable("Managers")
but as the OnModelCreating
method is only called once I can't map it to other table names on the fly.
In our current LinqToSql version we're overriding the MetaModel.GetTable() and returning a new TableAttribute with our dynamic name. I haven't found an attribute like that in EF (even if there were I wouldn't know how to override that yet). So my question is: Is it possible to do this (yet)?
Update
I've found that I can prevent the OnModelCreating
method from caching the mappings by calling
modelBuilder.CacheForContextType = false;
As a result I can assign table definitions on instantiation of the object. This isn't quite how I wanted to do it but it works.
Update
Oh boy, was the above a big mistake...Caching exists for a reason! :) So I'm back to square one with POCO object mapping. I'll post an update if I figure out a solution.
Final
Incase anybody cares how I've currently solved this issue, here you go:
First I created a separate library with the POCO tables and an Interface
public interface IDataContext {
System.Data.Entity.DbSet<TableGeneric> TableGeneric { get; set; }
int SaveChanges();
}
public class TableGeneric {
[Key]
public int Column1 { get; set; }
public string Column2 { get; set; }
public DateTime Column3 { get; set; }
public string Column4 { get; set; }
public string Column5 { get; set; }
}
Then, using the CSharpCodeProvider I created a class that takes the following template and turns it into a type definition:
class DataContext : System.Data.Entity.DbContext, IDataContext {
public System.Data.Entity.DbSet<TableGeneric> TableGeneric { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder
.Entity<ContextTesting.Interfaces.EF.TableGeneric()
.MapSingleType()
.ToTable("$TableName$");
}
}
With the generated type I'm able to create an instance so here we go
Type typeAccountants = BuildContext.CreateGenericTable("Accountants");
IDataContext context = (IDataContext)Activator.CreateInstance(typeAccountants);
Then the rest is just as if you had a normal DataContext. Hope this helps someone else.
Incase anybody cares how I've currently solved this issue, here you go:
First I created a separate library with the POCO tables and an Interface
public interface IDataContext {
System.Data.Entity.DbSet<TableGeneric> TableGeneric { get; set; }
int SaveChanges();
}
public class TableGeneric {
[Key]
public int Column1 { get; set; }
public string Column2 { get; set; }
public DateTime Column3 { get; set; }
public string Column4 { get; set; }
public string Column5 { get; set; }
}
Then, using the CSharpCodeProvider I created a class that takes the following template and turns it into a type definition:
class DataContext : System.Data.Entity.DbContext, IDataContext {
public System.Data.Entity.DbSet<TableGeneric> TableGeneric { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder
.Entity<ContextTesting.Interfaces.EF.TableGeneric()
.MapSingleType()
.ToTable("$TableName$");
}
}
With the generated type I'm able to create an instance so here we go
Type typeAccountants = BuildContext.CreateGenericTable("Accountants");
IDataContext context = (IDataContext)Activator.CreateInstance(typeAccountants);
Then the rest is just as if you had a normal DataContext. Hope this helps someone else.
这篇关于如何动态地将实体框架模型映射到表名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!