U bent misschien het slachtoffer van de EF Code-First mapping-conventies die automatisch een relatie creëren tussen NationAllies
en toNation
die je niet wilt hebben.
Als ik je goed begrijp (maar ik ben er niet 100 procent zeker van, als ik dat doe), wil je eigenlijk twee relaties hebben en je hebt slechts één uiteinde van de relatie in elk van de entiteiten blootgelegd. Dus, NationAllies
wijst NIET naar toNation
maar naar een "onzichtbare" Eigenaarsnatie in uw NationAlly
entiteit.
Als dat het geval is, moet u de conventietoewijzingen expliciet overschrijven. In de Fluent API van EF 4.1 zou dit er als volgt uit kunnen zien:
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);
}
}
Deze toewijzing zou de twee externe sleutels OwnerID
. creëren en NationID
in de NationAllies
tabel, beide wijzend naar de primaire sleutel ID
in de Nations
tafel.
Bewerken
Hier is de applicatie waarmee ik heb getest:
- Maak een nieuwe console-app in VS2010 / .NET 4.0, noem deze "NationsApp"
- Voeg een verwijzing toe naar "EntityFramework.dll"
- Wis de inhoud van "Program.cs" en plak in plaats daarvan het volgende in:
Inhoud van 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;
}
}
}
}
}
Je kunt een breekpunt instellen op "throw" om mogelijke uitzonderingen in e in de debugger te bekijken.
Dit creëert een database met de naam NationsApp.NationsContext
als u SQL Server Express gebruikt en geen verdere verbindingsreeksen hebt gedefinieerd.
Het geeft twee relaties Nation_NationAllies
(FK is "OwnerID") en NationAlly_toNation
(FK is "NationID"). Alle kolommen zijn niet-nullable. Het resultaat in de DB is het volgende: