Ich dachte, das würde einfach sein ... Ich habe eine Situation, wo ich eine Tabelle Module
, die "Basis" -Module enthalten kann, und "Compound" -Module (die aus bestehen 1-n Basismodule).Selbstreferenziert Tabelle in EF6
So habe ich diese beiden Tabellen in 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)
)
und ich in einigen Basismodulen gefüllt:
INSERT INTO dbo.Module (ModuleName)
VALUES ('Base Module #1'), ('Base Module #2'), ('Base Module #3')
Jetzt habe ich eine EF 6 „Code-first, Reverse -engineer aus der Datenbank“-Modell und bekommen diese Module
Klasse:
[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; }
}
und diese Kontextklasse:
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"));
}
}
Wenn ich jetzt versuchen, eine neue Verbindung Modul mit diesem Code zu erstellen, stellt sich heraus, sind die Dinge nicht ganz so einfach, wie ich dachte .....
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();
}
Dieser Code ein Fehler verursacht (auf der Linie versucht, das Basismodul # 1 zu holen):
System.Data.Entity.Core.EntityCommandExecutionException unhandled war
HResult = -2146232004
Meldung = Beim Ausführen der Befehlsdefinition ist ein Fehler aufgetreten. Weitere Informationen finden Sie in der inneren Ausnahme.
Source = EntityFrameworkInnerexception: System.Data.SqlClient.SqlException
HResult = -2146232060
Message = Ungültiger Spaltenname 'Module_ModuleId'.
Was fehlt mir hier ?? Und warum ist der Reverse-Engineering-Code von EF6 nicht intelligent genug, um ein Modell zu erstellen, das in diesem Fall funktioniert ??
Ich habe bisher EF4 mit Datenbank-First-Ansatz verwendet, so dass all diese fließende Code-First-Konfiguration ist immer noch ein Rätsel (und ein Problem) für mich ...... sieht jemand meine (höchstwahrscheinlich sehr) offensichtlicher Anfängerfehler ??
PS: das ist der Code, den die "Code-first-from-existing-Datenbank" Reverse-Engineering produziert - nicht mein eigenes. Warum funktioniert der Reverse Engineering-Ausgangscode am Ende nicht??
ich tun, um Ihr Szenario auf EF6.1.3 und keine Ausnahme aufgetreten! – ArMaN
Wie können Sie auf neue Compound.BaseModule zugreifen? ist es neuCompound.Module1? – ArMaN
@ArMaN: Ich kann dieses Problem nicht mehr reproduzieren, auch nicht ..... das ist wirklich wirklich komisch ....... Ich werde ein bisschen mehr untersuchen müssen, warum es jetzt plötzlich funktioniert .. .... –