Möglicherweise sind Sie ein Opfer der EF Code-First-Mapping-Konventionen, die automatisch eine Beziehung zwischen NationAllies
erstellen und toNation
die du nicht haben willst.
Wenn ich Sie richtig verstehe (aber ich bin mir nicht 100-prozentig sicher, ob ich das tue), möchten Sie eigentlich zwei Beziehungen haben, und Sie haben nur ein Ende der Beziehung in jeder der Entitäten offengelegt. Also, NationAllies
zeigt NICHT auf toNation
sondern an eine "unsichtbare" Eigentümernation in Ihrem NationAlly
Entität.
In diesem Fall müssen Sie die Konventionszuordnungen explizit überschreiben. In der Fluent-API von EF 4.1 könnte dies so aussehen:
public class MyContext : DbContext
{
public DbSet<Nation> Nations { get; set; }
public DbSet<NationAlly> NationAllies { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Nation>()
.HasMany(n => n.NationAllies)
.WithRequired()
.Map(conf => conf.MapKey("OwnerID"))
.WillCascadeOnDelete(false);
modelBuilder.Entity<NationAlly>()
.HasRequired(a => a.toNation)
.WithMany()
.Map(conf => conf.MapKey("NationID"))
.WillCascadeOnDelete(false);
}
}
Diese Zuordnung würde die beiden Fremdschlüssel OwnerID
erzeugen und NationID
in den NationAllies
Tabelle, die beide auf den Primärschlüssel ID
zeigen in den Nations
Tabelle.
Bearbeiten
Hier ist die Anwendung, mit der ich getestet habe:
- Erstellen Sie eine neue Konsolen-App in VS2010 / .NET 4.0, nennen Sie sie "NationsApp"
- Fügen Sie einen Verweis auf "EntityFramework.dll" hinzu
- Löschen Sie den Inhalt von "Program.cs" und fügen Sie stattdessen Folgendes ein in:
Inhalt von Program.cs:
using System;
using System.Collections.Generic;
using System.Data.Entity;
namespace NationsApp
{
public class Nation
{
public int ID { get; set; }
public int name { get; set; }
public List<NationAlly> NationAllies { get; set; }
}
public class NationAlly
{
public int ID { get; set; }
public int level { get; set; }
public Nation toNation { get; set; }
}
public class NationsContext : DbContext
{
public DbSet<Nation> Nations { get; set; }
public DbSet<NationAlly> NationAllies { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Nation>()
.HasMany(n => n.NationAllies)
.WithRequired()
.Map(conf => conf.MapKey("OwnerID"))
.WillCascadeOnDelete(false);
modelBuilder.Entity<NationAlly>()
.HasRequired(a => a.toNation)
.WithMany()
.Map(conf => conf.MapKey("NationID"))
.WillCascadeOnDelete(false);
}
}
class Program
{
static void Main(string[] args)
{
using (var context = new NationsContext())
{
try
{
// We have three Nations and two Allies
Nation nation1 = new Nation() {
NationAllies = new List<NationAlly>() };
Nation nation2 = new Nation() {
NationAllies = new List<NationAlly>() };
Nation nation3 = new Nation() {
NationAllies = new List<NationAlly>() };
NationAlly ally1 = new NationAlly();
NationAlly ally2 = new NationAlly();
// Nation1 has two Allies
// (Nation1 is the "owner" of both Allies)
nation1.NationAllies.Add(ally1);
nation1.NationAllies.Add(ally2);
// toNation of ally1 refers to Nation2
ally1.toNation = nation2;
// toNation of ally2 refers to Nation3
ally2.toNation = nation3;
context.Nations.Add(nation1);
context.Nations.Add(nation2);
context.Nations.Add(nation3);
context.SaveChanges();
}
catch (Exception e)
{
throw;
}
}
}
}
}
Sie können einen Haltepunkt auf "throw" setzen, um mögliche Ausnahmen in e im Debugger zu beobachten.
Dadurch wird eine Datenbank namens NationsApp.NationsContext
erstellt wenn Sie SQL Server Express verwenden und keine weiteren Verbindungszeichenfolgen definiert haben.
Es gibt zwei Beziehungen Nation_NationAllies
(FK ist "OwnerID") und NationAlly_toNation
(FK ist "NationID"). Alle Spalten sind nicht-nullable. Das Ergebnis in der DB ist folgendes: