Вы, возможно, являетесь жертвой соглашений EF Code-First, которые автоматически создают отношения между NationAllies
и toNation
, которые вы не хотите иметь.
Если я вас правильно понимаю (ноЯ не уверен на 100 процентов, если я это сделаю), вы на самом деле хотите иметь два отношения, и вы раскрыли только один конец отношений в каждой из сущностей.Таким образом, NationAllies
НЕ указывает на toNation
, но указывает на "невидимую" нацию владельца в вашей NationAlly
сущности.
В этом случае вам необходимо явно перезаписать отображения соглашений.В Fluent API в EF 4.1 это может выглядеть следующим образом:
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);
}
}
Это сопоставление создаст два внешних ключа OwnerID
и NationID
в таблице NationAllies
, оба указывают на первичный ключ ID
в таблице Nations
.
Редактировать
Вот приложение, которое я тестировал:
- Создание новой консолиПриложение в VS2010 / .NET 4.0, назовите его «NationsApp»
- Добавьте ссылку на «EntityFramework.dll»
- Очистите содержимое «Program.cs» и вставьте вместо него следующее:
Содержимое 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;
}
}
}
}
}
Вы можете установить точку останова на "throw", чтобы просмотреть возможные исключения в e в отладчике.
Thisсоздает базу данных с именем NationsApp.NationsContext
, если вы используете SQL Server Express и у вас не определены какие-либо дополнительные строки подключения.
Это дает две взаимосвязи Nation_NationAllies
(FK - "OwnerID") и NationAlly_toNation
(ФК это "NationID").Все столбцы не обнуляются.Результат в БД следующий: