Quizás sea víctima de las convenciones de mapeo EF Code-First que crean automáticamente una relación entre NationAllies
y toNation
no quieres tener.
Si te entiendo correctamente (pero no estoy 100 por ciento seguro, si lo hago), en realidad quieres tener dos relaciones y has expuesto solo un extremo de la relación en cada una de las entidades. Entonces, NationAllies
NO apunta a toNation
sino a una nación Propietaria "invisible" en su NationAlly
entidad.
Si ese es el caso, debe sobrescribir explícitamente las asignaciones de convenciones. En la API fluida de EF 4.1, esto podría verse así:
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);
}
}
Esta asignación crearía las dos claves foráneas OwnerID
y NationID
en los NationAllies
tabla, ambos apuntando a la clave principal ID
en las Nations
mesa.
Editar
Aquí está la aplicación con la que he probado:
- Cree una nueva aplicación de consola en VS2010 / .NET 4.0, asígnele el nombre "NationsApp"
- Agregue una referencia a "EntityFramework.dll"
- Borrar el contenido de "Program.cs" y pegar en su lugar lo siguiente en:
Contenido de 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;
}
}
}
}
}
Puede establecer un punto de interrupción en "lanzar" para observar posibles excepciones en e en el depurador.
Esto crea una base de datos llamada NationsApp.NationsContext
si está utilizando SQL Server Express y no tiene más cadenas de conexión definidas.
Da dos relaciones Nation_NationAllies
(FK es "ID de propietario") y NationAlly_toNation
(FK es "NationID"). Todas las columnas no aceptan valores NULL. El resultado en la BD es el siguiente: