无法使用CodeFirst以多对多关系将数据保存在联合表中

时间:2018-08-29 00:29:48

标签: asp.net-mvc entity-framework model-view-controller ef-code-first

我是EntityFramework的代码的新手。因此,我正在运行一些简单的测试来学习。我创建了两个类:团队和玩家,假设它们具有多对多关系。我还启用了迁移并添加了一些种子数据。运行更新数据库时,我看到种子数据填充了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 :(得分:1)

您是否尝试过在不使用迁移的情况下添加包含一些玩家的团队?

顺便说一句:尝试在构造函数中不创建HashSet的情况下进行此操作。这将浪费处理能力,因为它将由实体框架立即由其自己的ICollection代替。

以下内容在没有哈希集的普通Program.Main()中为我工作:

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),并且它可以工作。

建议:首先在不进行迁移的情况下使其运行,然后尝试在迁移中进行。用断点调试它,您真的要迁移吗?