0

我遇到的问题似乎可能是我的误解或实体框架的错误。

我有一个 .NET 4.0 ASP.NET Web 项目,它仅使用 GridView 和 Entity Framework 视图对象的数据源,只选择了一些列。

实体框架基于 SQL Server 2008 R2 中的数据库模型;表格设计主要是第三范式。

相关对象的快速数据库模式:

[t_User] 用户 ID、bigint、PK FirstName、varchar(50) LastName、varchar(50)

[t_Manager] MgrID, int, PK UserID, bigint, FK

[v_Manager] MgrID, int UserID, bigint FirstName, varchar(50) LastName, varchar(50)

当我将表和视图导入到我的 EF 模型中时,它从 v_Manager 为 PK 分配了 MgrID,我认为这很好。

v_Manager 驱动 ASPX GridView 控件,其中数据源设置为使用 v_Manager 实体的 EF 模型。

GridView 工作正常,我有它,页脚 CreateNew 行命令工作。

当我使用 GridView RowDeleting 触发器删除记录时出现问题,代码如下所示:

protected void MgrsGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
    // parse userId
    long mgrSelected = long.Parse(e.Values[0].ToString());

    using (DBEntity db = new DBEntity())
    {
        // select mgr object based on userid, (we don't select mgrid for the gridview bind)
        var mgrToDelete = db.t_Manager.Single(m => m.UserID == mgrSelected);

        if (mgrToDelete != null)
        {
            db.DeleteObject(mgrToDelete);
            db.SaveChanges();
            MgrGrid.DataBind();
        }
    }
}

我已经逐步完成了 RowDeleting() 的所有代码,它可以工作并且实际上删除了记录(在 SSMS 中验证),但是一旦 EF 代码运行,我在页面呈现时收到以下错误:

无法更新 EntitySet 'v_Manager',因为它有一个 DefiningQuery 并且元素中不存在支持当前操作的元素。

我没有尝试更新 v_Manager 也没有从中删除任何内容,我正在使用 t_Manager。我已经对收到的错误进行了堆栈和谷歌搜索,并手动更新了我的 edmx 文件以删除 DefiningQuery,但随后我直接从 SQL Server 2008 收到错误消息,说它无法从 v_Manager 中删除记录,因为它会影响多个表。

我在这里错过了什么吗?我认为从 t_Manager 实体中删除记录并调用 SaveChanges() 只会导致 SQL Server 在 v_Manager 实体上运行 Refresh() 不是吗?

我需要使用 v_Manager 实体来驱动 GridView,但我偷偷怀疑如果我将 GridView 更改为与 t_Manager 绑定,我不会有任何问题。

似乎问题来自由 v_Manager 驱动的 GridView 触发 RowDeleting 事件导致它对 GridViews 数据源运行删除。

有没有办法覆盖这种行为,或者这是设计使然,如果是这样,人们如何在使用视图(大多数数据库将使用)时发现 Entity Framework 有用?

感谢任何人提供的任何帮助,谢谢!

编辑:我应该提到我尝试设置 EnableDelete 标志 = false 并且只导致 Web 表单告诉我在单击 GridView 中的删除链接时数据源不允许删除。

4

1 回答 1

1

Reddit 上的 TobiasFunkeMD 值得称赞(再次感谢!) Reddit 链接

只需添加 e.Cancel = true; 在 GridView.DataBind() 之后;

例子:

db.DeleteObject(mgrToDelete);
db.SaveChanges();
MgrGrid.DataBind();

e.Cancel = true;

当您使用 e.CancelBubbling 时,这与在 javascript 中的工作方式相同,本质上它会阻止事件在链上继续进行。

实体框架运行良好,问题是 GridViews 自己的 RowDeleting 事件总是与 GridViews 自己的 DataSource 冲突,无论 RowDeleting 函数中正在做什么。

于 2012-07-06T05:43:41.140 回答