【问题标题】:Trouble Deleting Entity With Nav Property to View无法删除具有要查看的导航属性的实体
【发布时间】:2018-05-22 19:05:21
【问题描述】:

这是我正在使用的基本架构的精简示例。我意识到这个例子很复杂,但是这个模式的使用是有原因的,这对于描述我所看到的问题并不重要。

另外值得注意的是:我使用的是数据库优先。

团队(表)
身份证
名称

播放器(表)
身份证
团队ID
年份
名称
位置

游戏(桌)
身份证
日期
主队 ID
客队ID

GameHomePlayer_VW(视图)
GameId(在 EDMX 中定义为 PK)
HomePlayerId

View GameHomePlayer_VW 定义为:

SELECT
    Game.Id,
    Player.Id
FROM Game
LEFT OUTER JOIN Player
ON
    Game.HomeTeamId = Player.TeamId AND
    YEAR(Game.Date) = Player.Year

(如果你好奇,还有一个 GameAwayPlayer_VW :))

GameGameHomePlayer_VW 之间的 EDMX 关联:

Referential Constraint      Game -> GameHomePlayer_VW

End1 Multiplicity           0..1 (Zero or One of GameHomePlayer_VW)
End1 Navigation Property    Game
End1 OnDelete               None
End1 Role Name              GameHomePlayer_VW
End2 Multiplicity           1 (One of Game)
End2 Navigation Property    GameHomePlayer_VW
End2 OnDelete               None
End2 Role Name              Game
Name                        GameHomePlayer_VWGame

GameGameHomePlayer_VW EF 生成的类:

public partial class Game
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public Nullable<int> HomeTeamId { get; set; }
    public Nullable<int> AwayTeamId { get; set; }

    public virtual Team HomeTeam { get; set; }
    public virtual Team AwayTeam { get; set; }
    public virtual GameHomePlayer_VW GameHomePlayer_VW { get; set; }
    public virtual GameAwayPlayer_VW GameAwayPlayer_VW { get; set; }
}

public partial class GameHomePlayer_VW
{
    public int GameId { get; set; }
    public Nullable<int> PlayerId { get; set; }

    public virtual Game Game { get; set; }
    public virtual Player Player { get; set; }
}

此设置允许我这样查询视图对象:

private async Task<Game> GetGame(int id)
{
    return await Context.Games
        .Include(i => i.GameHomePlayer_VW.Player)
        .Include(i => i.GameAwayPlayer_VW.Player)
        .FirstOrDefaultAsync(i => i.Id == id);
}

我用来删除游戏的代码如下:

private async Task DeleteGame(int id)
{
    var game = await Context.Games.FirstOrDefaultAsync(i => i.Id == id);
    Context.Games.Remove(game);
    await Context.SaveChangesAsync();
}

我遇到的问题是,当我尝试使用 EF 删除游戏实体时,我收到以下错误:

无法更新 EntitySet 'GameHomePlayer_VW',因为它有一个 DefiningQuery 并且&lt;ModificationFunctionMapping&gt; 元素中不存在支持当前操作的&lt;DeleteFunction&gt; 元素。

还有其他实体引用游戏并使用级联删除来删除。

我尝试使用这篇帖子中的解决方案没有成功:Unable to update the EntitySet - because it has a DefiningQuery and no <UpdateFunction> element exist

我还尝试连接一个存储过程,该过程采用 EDMX 定义的 PK 并返回 0。

我尝试初始化我的 DbContext 类的新实例以将其删除,如下所示,但仍然遇到同样的问题。

private async Task DeleteGame(int id)
{
    using (var context = new MyDbContext)
    {
        var game = await context.Games.FirstOrDefaultAsync(i => i.Id == id);
        context.Games.Remove(game);
        await context.SaveChangesAsync();
    }
}

是否有人对维护基于游戏日期的动态链接同时允许添加/更新/删除引用它的实体有任何建议?

【问题讨论】:

  • 您是如何尝试删除游戏的?您应该显示发生这种情况的代码。看起来您正在尝试为此使用视图,但为什么呢?
  • 格特,感谢您的提示。我现在意识到,如果不记录删除代码,我会遗漏一大块拼图!
  • 这让我怀疑Context的生命周期太长了。如果是这样,当您让Game 删除它时,之前加载的...._VW 实体仍然附加到它并标记为删除。
  • 我尝试实例化我的 DbContext 类的新实例来删除游戏,但仍然看到同样的问题。 Context 变量被注入到我用于每个 API 请求的控制器中。因此,我没想到会有一个新实例来解决问题,但你的预感引起了我的共鸣。
  • 好的,情节变厚了...当 EF 删除一个实体时,它也会尝试切断它拥有的任何关联。在这种情况下,这可能意味着 EF 想要更新视图实体。这将有助于查看实际类的代码以了解关联是如何工作的。

标签: c# .net sql-server entity-framework entity-framework-6


【解决方案1】:

我最终通过为每个需要映射的实体创建Pure Join Tables 来解决这个问题,并根据之前视图中的逻辑在 Game 表上编写触发器以插入、更新或删除映射表中的记录.

EF 更乐意添加/编辑/删除在此之后附加到它们的实体。

GameHomePlayerMap(表格)
GameId(PK、FK 到游戏)
HomePlayerId(FK 到播放器)

GameAwayPlayerMap(表格)
GameId(PK、FK 到游戏)
AwayPlayerId(FK 到玩家)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-26
    • 2013-10-28
    相关资源
    最近更新 更多