我正在使用EF6开发一个插件应用程序,代码优先。
我有一个名为User
的实体的主要上下文:
public class MainDataContext : DbContext
{
public MainDataContext(): base("MainDataContextCS") {}
public DbSet<User> Users { get; set; }
}
然后是PluginX的另一个上下文,在另一个引用基本项目的项目中:
public class PluginDataContext : DbContext
{
public PluginDataContext () : base("MainDataContextCS") {
}
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.HasDefaultSchema("PluginX");
base.OnModelCreating(modelBuilder);
}
public DbSet<Booking> Bookings { get; set; }
}
这可以在同一个数据库(相同的连接字符串)上整齐地创建PluginX.Bookings
表。
此处的问题是Booking
实体包含对User
实体的引用:
public class Booking
{
public int Id { get; set;}
public virtual User CreationUser { get; set;}
public BookingStatus Status { get; set; }
}
当为插件上下文运行Add-Migration
时,EF会尝试创建另一个名为User
的{{1}}实体。
如何解决这个问题?有没有办法在另一个PluginX.User
?
答案 0 :(得分:6)
当您使用多个上下文时,您有两个选择:
答案 1 :(得分:2)
此解决方案可以帮助您:Entity Framework 6 Code First Migrations with Multiple Data Contexts。但是,在这种情况下,两个上下文都在同一个项目中。我不知道是否适用于两个不同项目中的上下文(我认为如果您使用相同的类来映射用户应该这样做)。正如博客所说,当您为PluginX Context运行Add-Migration
命令时,需要注释与Users表相关的生成代码。
答案 2 :(得分:1)
添加预订实体时,请勿使用DbSet.Add()
方法。而是使用DbSet.Attach()
方法并将预订的DbContext.Entry(Entity).State
属性设置为EntityState.Added
,并确保用户的DbContext.Entry(Entity).State
保留EntityState.Unchanged
。
例如,而不是这样做:
pluginDataContext.dbBooking.Add(myNewBooking);
这样做:
pluginDataContext.dbBooking.Attach(myNewBooking);
pluginDataContext.Entry(myNewBooking).State = EntityState.Added;
这是因为Add()
方法将对象图中的所有实体标记为EntityState.Added
,这将导致插入而不检查实体是否已存在于数据库中。 Attach()
方法只是让上下文开始跟踪实体。
这就是为什么我几乎从不使用DbSet.Add()
。
答案 3 :(得分:0)
您可以尝试使用视图,在PluginDataContext中将用户声明为视图,然后在执行迁移时,键入“创建用户视图为...”方法,这使您可以将书与用户相关联。