2014-12-09 2 views
1

У меня есть две модели Team и плеерEF установить внешний ключ нуль на родителя удалить

public class Player 
    { 
      public int Id { get; set; } 
    } 

    public class FootballPlayer : Player 
    { 
     public int? TeamId { get; set; } 

     public virtual FootballTeam Team { get; set; } 
    } 

    public class BasketballPlayer : Player 
    { 
     public int? TeamId { get; set; } 

     public virtual BasketballTeam Team { get; set; } 
    } 

    public class BasketballTeam : Team 
    { 
     public int Id { get; set; } 
     public virtual List<BasketballPlayer> Players { get; set; } 
    } 

public class FootballTeam : Team 
    { 
     public int Id { get; set; } 
     public virtual List<FootballPlayer > Players { get; set; } 
    } 

Вот конфигурация

 protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 

     modelBuilder.Entity<FootballPlayer>().HasOptional(r => r.Team) 
     .WithMany(a => a.Players) 
     .HasForeignKey(b => new { b.TeamId }) 
     .WillCascadeOnDelete(false); 

     modelBuilder.Entity<BasketballPlayer>().HasOptional(r => r.Team) 
     .WithMany(a => a.Players) 
     .HasForeignKey(b => new { b.TeamId }) 
     .WillCascadeOnDelete(false); 

     base.OnModelCreating(modelBuilder); 
    } 

Я использую EF Code First и я хочу, чтобы сделать это, когда Я удаляю команду, игроки не должны удаляться только TeamId, установленным в null. Как это можно сделать?

+1

Вы изучили использование WillCascadeOnDelete (false) при настройке отношений? – SBirthare

+0

Теперь я работаю, но проблема, когда я хочу получить команду, она больше не получает игроков, даже если игрок принадлежит команде – user2412672

+0

. Я добавил конфигурацию, которую я добавил и работал для меня. Я могу удалить, см. Null для TeamId в БД. Затем я запросил элемент, который имеет Null, все работает отлично. Попробуйте. – SBirthare

ответ

1

Вот конфигурация, которую я определил для лица:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Player>().HasOptional(r => r.Team) 
      .WithMany(a => a.Players) 
      .HasForeignKey(b => new { b.TeamId }) 
      .WillCascadeOnDelete(false); 

     base.OnModelCreating(modelBuilder); 
    } 

Update

Над конфигурации работали для исходных объектов, то есть простые один-ко-многим (Team-> Игроки) , Новые объекты включают в себя наследование, которое неожиданно устраняет эффект вышеупомянутой конфигурации.

С новыми объектами конфигурация остается прежней (HasOptional и CascadeOnDelete), однако она не позволяет удалять команду, которая используется любым игроком. Он бросает

{ "УДАЛИТЬ утверждение противоречит ОБРАЩЕНИЯ ограничения \" FK_dbo.FootballPlayers_dbo.FootballTeams_TeamId \ "Конфликт произошел в базе данных \ "EF6Testing.StudentContext \", таблица \" dbo.FootballPlayers \ "столбец 'TeamID'. \ г утверждение \ NThe была прекращена."}

Это связано с ограничением ([FK_dbo.FootballPlayers_dbo.FootballTeams_TeamId]), что EF добавляет в одном случае для многих отношениях , Тем не менее, для меня это не ясно, то же ограничение было добавлено в Team-> Players case, и EF удобно «не применял ограничение внешнего ключа».

Итак, почему EF не позволяет удалять команду, когда сущности имеют иерархию наследования ???

Хорошо, давайте оставим эту тайну эксперту EF, чтобы решить.

Решение (одно из возможных решений) для решения этой проблемы заключается в том, что вам придется выполнить сценарий SQL, чтобы удалить и создать ограничение. Этот скрипт установит значение, заносимое в ключ.

Мне интересно узнать ответ на этот вопрос и если в EF (5 или 6 или более поздняя версия) есть лучшее решение для решения этой проблемы.

USE [@DatabaseName] 
GO 

ALTER TABLE [dbo].[FootballPlayers] DROP CONSTRAINT [FK_dbo.FootballPlayers_dbo.FootballTeams_TeamId] 
GO 

ALTER TABLE [dbo].[FootballPlayers] WITH CHECK ADD CONSTRAINT [FK_dbo.FootballPlayers_dbo.FootballTeams_TeamId] FOREIGN KEY([TeamId]) 
REFERENCES [dbo].[FootballTeams] ([Id]) on delete set null 
GO 

ALTER TABLE [dbo].[FootballPlayers] CHECK CONSTRAINT [FK_dbo.FootballPlayers_dbo.FootballTeams_TeamId] 
GO 
+0

Теперь, когда я пытаюсь удалить команду, у которой есть игроки, я получаю это исключение: «Операция DELETE противоречила ограничению REFERENCE« FK_dbo.Players_dbo.Teams_TeamId ». Конфликт произошел в базе данных« SportsStats », таблице« dbo » .Players ", столбец 'TeamId'. Оператор завершен. « – user2412672

+0

@ user2412672 - Можете ли вы показать свою конфигурацию, вы должны установить отношения HasOptional, как показано в моем ответе. Используя приведенную выше конфигурацию, я могу удалить команду. – SBirthare

+0

modelBuilder.Entity () .AasOptional (r => r.Team) .WithMany (a => a.Players) .HasForeignKey (b => new {b.TeamId}) .WillCascadeOnDelete (false); – user2412672