【问题标题】:Cannot save data in the joint table in many to many relationship using codefirst无法使用codefirst在多对多关系中保存联合表中的数据
【发布时间】:2018-08-29 00:29:47
【问题描述】:

我首先是 EntityFramework 代码的新手。所以我正在运行一些简单的测试来学习。我创建了两个类:Team 和 Player,假设它们具有多对多关系。我还启用了迁移并添加了一些种子数据。当我运行 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)。我不知道为什么!

【问题讨论】:

  • 我认为您必须手动添加到映射表,就像您为 Team 和 Player 类所做的那样。

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


【解决方案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)并且它有效。

建议:首先让它在没有迁移的情况下工作,然后尝试在迁移中进行。用断点调试,你真的要迁移吗?

【讨论】:

    猜你喜欢
    • 2018-01-09
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多