Невозможно сохранить данные в объединенной таблице во многих отношениях, используя codefirst - PullRequest
0 голосов
/ 29 августа 2018

Сначала я новичок в коде EntityFramework. Итак, я провожу несколько простых тестов для изучения. Я создал два класса: «Команда» и «Игрок», которые гипотетически связаны между собой. Я также включил миграцию и добавил некоторые начальные данные. Когда я запускаю update-database, я вижу, что начальные данные заполняют таблицы Teams и Players, но таблица TeamPlayers пуста. Любые подсказки, что не так в коде? (Я удалил пакетные включения здесь для простоты представления)

namespace CodeFirst_onetomany.Models
{
    public class Team
    {
        public Team()
        {
            this.Players = new HashSet<Player>();
        }

        public int Id { get; set; }
        public string TeamName { get; set; }

        public virtual ICollection<Player> Players { get; set; }
    }
}

namespace CodeFirst_onetomany.Models
{
    public class Player
    {
        public Player()
        {
            this.Teams = new HashSet<Team>();
        }

        public int Id { get; set; }
        public string FirstName { get; set; }
        [Required]
        public string LastName { get; set; }

        public virtual ICollection<Team> Teams { get; set; }
    }
}

namespace CodeFirst_onetomany.Models
{
    public class MyContext : DbContext
    {
        public MyContext() : base("MyDbOneToMany")
        {

        }

        public DbSet<Team> Teams { get; set; }
        public DbSet<Player> Players { get; set; }
    }
}

namespace CodeFirst_onetomany.Migrations
{
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<CodeFirst_onetomany.Models.MyContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(CodeFirst_onetomany.Models.MyContext context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p => p.FullName,
            //      new Person { FullName = "Andrew Peters" },
            //      new Person { FullName = "Brice Lambson" },
            //      new Person { FullName = "Rowan Miller" }
            //    );
            //

            context.Teams.AddOrUpdate(t => t.TeamName, new Team() { TeamName = "AC Milan" });
            context.Teams.AddOrUpdate(t => t.TeamName, new Team() { TeamName = "Barcelona" });

            context.SaveChanges();

            context.Players.AddOrUpdate(p => new { p.FirstName, p.LastName },
                new Player()
                {
                    FirstName = "Paolo",
                    LastName = "Maldini",
                    Teams = new List<Team>() { context.Teams.FirstOrDefault(t => t.TeamName == "AC Milan") }
                });

            context.Players.AddOrUpdate(p => new { p.FirstName, p.LastName },
                new Player()
                {
                    FirstName = "Leo",
                    LastName = "Messi",
                    Teams = context.Teams.ToList()
                });

            context.SaveChanges();
        }
    }
}

Редактировать: Итак, я удалил HashSets (спасибо за информацию об этом @Harald Coppoolse) и начал хранить информацию в переменных, чтобы я мог ее отладить ... Я также добавил две дополнительные строки, добавив команды в конце игроков. Так что у меня частично есть:

context.Players.AddOrUpdate(p => new { p.FirstName, p.LastName }, maldini);
context.Players.AddOrUpdate(p => new { p.FirstName, p.LastName }, messi);
context.Players.FirstOrDefault(p => p.FirstName == "Paolo").Teams = shouldBeMilan;
context.Players.FirstOrDefault(p => p.FirstName == "Leo").Teams = shouldBeBarcaMilan;

context.SaveChanges();

и теперь это работает. Так что я думаю, что в EF нужно было бы вручную добавить отношения между игроками и командами, и мы не можем полагаться на создание объекта (то есть, используя new). Хотя я понятия не имею, почему!

1 Ответ

0 голосов
/ 29 августа 2018

Вы пытались добавить команду с несколькими игроками, не используя миграции?

Кстати: попробуйте это без создания HashSet в конструкторе. Это пустая трата вычислительной мощности, поскольку она будет немедленно заменена структурой сущности на собственную ICollection.

В обычной программе у меня сработало следующее. Основной () без хэш-кода:

using (var dbContext = new MyDbContext(...)
{
     var team1 = dbContext.Teams.Add(new Team() {TeamName = "Team 1"});

     var team2 = dbContext.Teams.Add(new Team()
     {
          TeamName = "My Super Team",
          Players =  new List<Player>()
          {
               new Player() {FirstName = "Christopholo", LastName = "Columbo"},
               new Player() {FirstName = "Marco", LastName = "Polo"},
          },
     });

     var player1 = dbContext.Players.Add(new Player()
     {
          FirstName = "X1",
          LastName = "Y1",
     });

     var player2 = dbContext.Players.Add(new Player()
     {
          FirstName = "X2",
          LastName = "Y2",
          Teams = new List<Team>() {team1, team2, new Team() {TeamName = "Team3"});
     });

     dbContext.SaveChanges();

     var teams = dbContext.Teams.Select(team => new
         {
             Id = team.Id,
             Name = team.Name,
             Players = team.Players.Select(player => new
             {
                 Id = player.Id,
                 LastName = player.LastName,
             })
             .ToList(),
         })
         .ToList();

     var players = dbContext.Players.Select(player => new
         {
              Id = player.Id,
              LastName = player.LastName,
              Teams = player.Teams.Select(team => new
              {
                  Id = team.Id,
                  Name = team.TeamName,
              })
              .ToList(),
         })
         .ToList();
         .ToList();
}

Это работает? А что, если вы добавите игрока в эту команду?

// add a Player using the Team's collection:
var teamToUpdate = dbContext.Teams.Where(team => team.Id ==team1.Id;
teamToUpdate.Players.Add(new Player() {FirstName = "...", LastName = "..."});

// add a Player and give him a Team:
var addedPlayer = dbContext.Player(new Player()
{
     FirstName = ...,
     LastName = ...,
     Teams = new List<Team>() {teamToUpdate},
})
dbContext.SaveChanges();

А что будет, если вы сделаете это при использовании AddOrUpdate?

Я пробовал это (все без HashSet), и это работает.

Совет: сначала запустите его без миграции, затем попробуйте сделать это в процессе миграции. Отладка с помощью точек останова, вы действительно мигрируете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...