使用Nav属性删除实体以查看

时间:2018-05-22 19:05:21

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

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

另外值得注意的是:我正在使用Database First。

团队(表格)
标识
名称

玩家(表格)
标识
TeamId

名称
位置

游戏(表格)
标识
日期
HomeTeamId
AwayTeamId

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
EF生成的

GameGameHomePlayer_VW类:

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,<DeleteFunction>元素中不存在<ModificationFunctionMapping>元素以支持当前操作。

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

我尝试在此帖子中使用解决方案失败: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();
    }
}

是否有人建议根据游戏日期维护动态链接,同时允许引用它的实体被添加/更新/删除?

1 个答案:

答案 0 :(得分:0)

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

EF非常高兴添加/编辑/删除之后附加到它们的实体。

GameHomePlayerMap(表格)
GameId(PK,FK to Game)
HomePlayerId(FK to Player)

GameAwayPlayerMap(表)
GameId(PK,FK to Game)
AwayPlayerId(FK to Player)