我认为这会很容易......我有一个 table Module
,它可以包含“基本”模块和“复合”模块(由 1-n 个基本模块组成)。
所以我在 SQL Server 2014 中有这两个表:
CREATE TABLE Module
(
ModuleId INT NOT NULL IDENTITY(1,1)
CONSTRAINT PK_Module PRIMARY KEY CLUSTERED,
ModuleName VARCHAR(100)
)
CREATE TABLE CompoundModule
(
CompoundModuleId INT NOT NULL
CONSTRAINT FK_CompoundModule_MainModule
FOREIGN KEY REFERENCES dbo.Module(ModuleId),
BaseModuleId INT NOT NULL
CONSTRAINT FK_CompoundModule_BaseModules
FOREIGN KEY REFERENCES dbo.Module(ModuleId),
CONSTRAINT PK_CompoundModule
PRIMARY KEY CLUSTERED(CompoundModuleId, BaseModuleId)
)
我填写了一些基本模块:
INSERT INTO dbo.Module (ModuleName)
VALUES ('Base Module #1'), ('Base Module #2'), ('Base Module #3')
现在我创建了一个 EF 6“代码优先,数据库逆向工程”模型并获得了这个Module
类:
[Table("Module")]
public partial class Module
{
public Module()
{
Module1 = new HashSet<Module>();
Module2 = new HashSet<Module>();
}
public int ModuleId { get; set; }
public string ModuleName { get; set; }
public virtual ICollection<Module> Module1 { get; set; }
public virtual ICollection<Module> Module2 { get; set; }
}
和这个上下文类:
public partial class ModuleCtx : DbContext
{
public ModuleCtx() : base("name=ModuleCtx")
{ }
public virtual DbSet<Module> Module { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Module>()
.Property(e => e.ModuleName)
.IsUnicode(false);
modelBuilder.Entity<Module>()
.HasMany(e => e.Module1)
.WithMany(e => e.Module2)
.Map(m => m.ToTable("CompoundModule").MapLeftKey("BaseModuleId").MapRightKey("CompoundModuleId"));
}
}
当我现在尝试用这段代码创建一个新的复合模块时,结果发现事情并不像我想象的那么容易......
using (ModuleCtx ctx = new ModuleCtx())
{
Module newCompound = new Module();
Module baseModule1 = ctx.Module.FirstOrDefault(m => m.ModuleId == 1);
Module baseModule3 = ctx.Module.FirstOrDefault(m => m.ModuleId == 3);
newCompound.BaseModules.Add(baseModule1);
newCompound.BaseModules.Add(baseModule3);
ctx.Module.Add(newCompound);
ctx.SaveChanges();
}
此代码导致错误(在尝试获取基本模块 #1 的行上):
System.Data.Entity.Core.EntityCommandExecutionException 未处理
HResult=-2146232004
消息=执行命令定义时发生错误。有关详细信息,请参阅内部异常。
来源=实体框架InnerException:System.Data.SqlClient.SqlException
HResult=-2146232060
消息=无效的列名“Module_ModuleId”。
我在这里想念什么?为什么 EF6 逆向工程代码不够聪明,无法创建适用于这种情况的模型?
到目前为止,我一直在使用 EF4 和数据库优先的方法,所以所有这些流畅的代码优先配置对我来说仍然有点神秘(和问题)......有人看到我的(很可能非常)明显的菜鸟错误??
PS:这是“现有数据库中的代码优先”逆向工程产生的代码 - 不是我自己的。那么为什么逆向工程输出的代码最终还是不行呢??