删除与基于视图的实体具有一对多关联的实体对象

Deleting Entity Object with 1 to Many Association to View-Based Entity

我有一个 Model-First 实体模型,其中包含一个 Customer table 链接到一个视图,该视图从一个单独的数据库中获取客户详细信息。客户 table 和视图之间的关系是一对多的,我在客户实体和视图实体上都有一个导航 属性。

当我尝试使用 context.Customers.DeleteObject(cust) 执行删除并调用 context.SaveChanges() 时,出现错误:

Unable to update the EntitySet 'ViewEntity' because it has a DefiningQuery and no [DeleteFunction] element exists element to support the current operation.


我试过设置 On Delete Cascade 和 None 并且都产生相同的错误。

编辑:没有太多代码可以展示,但你可以:

Customer selectedCust = (Customer)dgvCustomers.SelectedRows[0].DataBoundItem;
if (selectedCust != null)
{
    if (MessageBox.Show(String.Format("Are you sure you want to delete Customer {0}?", selectedCust.CustomerID.ToString()), 
                            "Customer Delete Confirmation", MessageBoxButtons.YesNo) == DialogResult.Yes)
    {
        // TODO - Fix this
        this.ReportSchedDBContext.Customers.DeleteObject(selectedCust);
        this.ReportSchedDBContext.SaveChanges();                      
    }
}

SO 中的许多相关帖子都同意@Overmachine 的观点...您可能缺少 entity/table 上的主键。

见..

because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element

Unable to update the EntitySet - because it has a DefiningQuery and no <UpdateFunction> element exist


编辑

刚刚看到您关于 Customer table 有主键但您的观点没有的评论。不确定没有更多代码会发生什么,但最终您需要的是一个设置了主键的 Customer 对象,然后您可以使用以下代码删除分离的实体对象。

this.ReportSchedDBContext.Entry(selectedCust).State = EntityState.Deleted;
this.ReportSchedDBContext.SaveChanges();  

如果您是从另一种类型进行转换而导致出现问题,您也可以这样做:

var cust = new Customer { CustomerID = selectedCust.CustomerID };
this.ReportSchedDBContext.Entry(cust).State = EntityState.Deleted;
this.ReportSchedDBContext.SaveChanges();  

我能够通过创建一个不执行任何操作的虚拟存储过程 ("SELECT 'Done'") 并在我的两个视图中使用 SP 函数映射将删除函数设置为此存储过程来解决此问题。相当骇人听闻,但它奏效了。

我不确定为什么视图需要删除函数,或者我是否做错了什么导致了这个问题,但以上方法对我有用。

我认为您应该在视图中使用所有外键。当您在视图中使用所有外键和主键时,您可以级联更新和删除对象。