实体框架 4.联接表.实体框架在不需要任何操作时执行插入

本文关键字:实体 框架 操作 执行 插入 任何 不需要 | 更新日期: 2023-09-27 17:55:42

我有一个数据库设置,包括以下内容:-

Person Table  
Hobby Table
Game Table  
GameInfo Table  
人 [1 - M] 爱好 [1 - M] 游戏

[M - 1] 游戏信息

Game只是从HobbyGameInfo的连接

我遇到了一个问题,我会获取Person具有Collection<Game>并添加到此集合中(即我只是更新链接,不想插入新的GameInfo)。

调用SaveChanges() EntityFramework 将插入链接以及插入新的GameInfo,这不是我想要的结果。

我看过 Entry()。状态等,但问题是我处理Person更新的地方不在上下文中。

我基本上是在获取一个Person创建一个具有我知道已经存在的 ID 的新Game,然后调用SaveChanges(),并期望它只会插入到Game表中,而不是 GameInfo 表中

编辑1:代码示例 - 排序

public void Save(Profile profile)
{
    using (GDContext context = GetContext())
    {
        DataProfile dataProfile = context.Profiles.Single(u => u.ProfileId == profile.Id);
        ProfileHandler.HandleDataModelChanges(dataProfile, profile);
        context.SaveChanges();
    }
}
public override void HandleDataModelChanges(DataProfile dataModel, Profile model)
{
    dataModel.ProfileId = model.Id;
    dataModel.FirstName = model.FirstName;
    dataModel.LastName = model.LastName;
    dataModel.DateOfBirth = model.DateOfBirth;
    dataModel.Email = model.Email;
    foreach(var hobby in model.Hobbies)
    {
        DataHobby dataHobby = dataModel.Hobbies.SingleOrDefault(p => p.HobbyId == hobby.HobbyId);
        if (dataHobby == null)
        {
            dataHobby = new DataHobby();
        }
        HobbyHandler.HandleDataModelChanges(dataHobby, hobby);
    }
}
public override void HandleDataModelChanges(DataHobby dataModel, Hobby model)
{
    dataModel.HobbyId = model.Id;
    HandleGames(dataModel, model);
    HandleCrafts(dataModel, model);
    HandleCollections(dataModel, model);
}
private void HandleGames(DataHobby dataModel, Hobby model)
{
    IEnumerable<DataGame> gamesToRemove = dataModel.Games.Where(g => !model.Games.Any(ds => ds.Id == g.GameId)).ToArray();
    foreach (var game in gamesToRemove)
    {
        dataModel.Games.Remove(game);
    }
    foreach (var game in model.Games)
    {
        if (!dataModel.Games.Any(e => e.GameId == game.Id))
        {
            DataGame dataGame = new DataGame();
            dataGame.GameId = game.Id;
            dataGame.GameName = game.Name;
            dataModel.Games.Add(dataGame);
        }
    }
}

编辑 2 - 上下文配置

this.Configuration.LazyLoadingEnabled = false;
this.Configuration.AutoDetectChangesEnabled = true;
public GameInfoConfiguration()
{
    HasKey(x => x.GameId);
    ToTable("GameData");
}
public PersonConfiguration()
{
    HasKey(x => x.PersonId);
    ToTable("Person");
}
public HobbyConfiguration()
{
    HasKey(x => x.HobbyId);
    HasRequired(x => x.Person).WithMany(x => x.Hobbies);
    HasMany(x => x.Games).WithMany(g => g.Hobbies).Map(x => x.MapLeftKey("HobbieId").MapRightKey("GameId").ToTable("PersonGame"));
    ToTable("HobbyGame");
}

实体框架 4.联接表.实体框架在不需要任何操作时执行插入

好吧,

我仍然没有看到您使用GameInfo的地方 - 您的描述绝对与您的代码不符。通过查看您的代码,我想问题将出在这样的片段中:

foreach (var game in model.Games)
{
    if (!dataModel.Games.Any(e => e.GameId == game.Id))
    {
        DataGame dataGame = new DataGame();
        dataGame.GameId = game.Id;
        dataGame.GameName = game.Name;
        dataModel.Games.Add(dataGame);
    }
}

这将始终插入新Game - 你告诉 EF 插入一个新Game。如果要添加现有Game必须执行以下操作:

foreach (var game in model.Games)
{
    if (!dataModel.Games.Any(e => e.GameId == game.Id))
    {
        DataGame dataGame = new DataGame();
        dataGame.GameId = game.Id;
        dataGame.GameName = game.Name;
        context.Games.Attach(dataGame); // Now the context knows that it is not a new entity 
        dataModel.Games.Add(dataGame);
    }
}
我认为

我在这里犯的错误是我正在处理DataGame而实际上我应该处理的是一个 POCO 类来表示DataGameHobby之间的"连接",就像一个HobbyGame POCO