无法更新EntitySet – 因为它有一个DefiningQuery并且不存在<UpdateFunction>元素

我正在使用.net 3.5entity framework1。

我正在做这样简单的事情:

var RoomDetails = context.Rooms.ToList(); foreach (var Room in Rooms) { Room.LastUpdated = DateTime.Now; } 

我正在尝试执行时遇到此错误:

  context.SaveChanges(); 

我得到的错误:

无法更新EntitySet – 因为它具有DefiningQuery,并且<ModificationFunctionMapping>元素中不存在<UpdateFunction>元素以支持当前操作。

我在上下文中做了很多更新,没有任何问题,只是当我试图更新这个特定的实体。

我所有的search都显示了同样的事情,即在我试图更新的实体上没有声明主键。 但是,唉,我确实有一个主键声明…

这通常是由于以下原因之一所致:

  • 实体集从数据库视图映射
  • 自定义数据库查询
  • 数据库表没有主键

这样做之后,您可能仍然需要在entity frameworkdevise器中进行更新(或者删除实体,然后添加它),然后再停止获取错误。

只需将一个主键添加到表中。 而已。 问题解决了。

 ALTER TABLE <TABLE_NAME> ADD CONSTRAINT <CONSTRAINT_NAME> PRIMARY KEY(<COLUMN_NAME>) 

这是我的情况。 简单地删除导致另一个错误。 除了最后一个,我跟着这篇文章的步骤。 为了方便起见,我复制了后面的四个步骤来解决问题,如下所示:

  1. 右键点击edmx文件,selectOpen with,XML编辑器
  2. 在edmx:StorageModels元素中find实体
  3. 完全删除DefiningQuery
  4. 重命名store:Schema="dbo"Schema="dbo" (否则,代码将产生一个错误,表明该名称是无效的)

只要注意,也许你的实体主键,你的数据库的表没有主键

更新:最近我得到了一些赞扬,所以我想我会让人们知道我给出的build议不是最好的。 由于我最初是在旧的无钥匙数据库上开始使用Entity Framework,所以我意识到,BY FAR所能做的最好的事情就是通过反编码来实现。 那里有一些很好的文章如何做到这一点。 只要按照他们,然后当你想添加一个关键,使用数据注释来“伪造”的关键。

例如,假设我知道我的表格Orders (虽然没有主键),但确保每个客户只有一个订单号码。 由于这些是表格中的前两列,所以我将代码设置为类,如下所示:

  [Key, Column(Order = 0)] public Int32? OrderNumber { get; set; } [Key, Column(Order = 1)] public String Customer { get; set; } 

通过这样做,你基本上伪装成EF相信有一个由OrderNumber和Customer组成的集群键。 这将允许您在无钥匙桌上插入,更新等。

如果你不太熟悉逆向代码优先,那么去entity framework代码优先找一个好的教程。 然后去反向代码优先(这是做Code First与现有的数据库)之一。 然后回到这里再看看我的主要build议。 🙂

原始答案

首先:正如其他人所说,最好的select是在表中添加一个主键。 句号 如果你能做到这一点,请不要再阅读。

但是,如果你不能,或者只是憎恨自己,就有办法在没有主键的情况下做到这一点。

在我的情况下,我正在使用一个遗留系统(AS400上最初的平面文件,移植到Access,然后移植到T-SQL)。 所以我必须find一个方法。 这是我的解决scheme。 以下是使用Entity Framework 6.0(NuGet的最新版本)编写的。

  1. 右键单击解决scheme资源pipe理器中的.edmx文件。 select“打开方式…”,然后select“XML(文本)编辑器”。 我们将在这里手动编辑自动生成的代码。

  2. 寻找这样的一条线:
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">

  3. 从最后删除store:Name="table_name"

  4. 更改store:Schema="whatever" Schema="whatever"

  5. 看下面这行,find<DefiningQuery>标签。 它会有一个大的select陈述。 删除标签和它的内容。

  6. 现在你的行应该看起来像这样:
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />

  7. 我们还有其他的东西要改变。 通过你的文件,find这个:
    <EntityType Name="table_name">

  8. 在附近,您可能会看到一些注释文本,警告您没有标识主键,因此已经推断了键,定义是只读表/视图。 您可以保留或删除它。 我删了它。

  9. 以下是<Key>标签。 这是entity framework将用于插入/更新/删除的内容。 所以请确保你做到这一点。 该标签中的属性(或属性)需要指明一个唯一可识别的行。 例如,假设我知道我的表格orders ,而没有主键,我们保证每个客户只有一个订单号码。

所以我看起来像:

 <EntityType Name="table_name"> <Key> <PropertyRef Name="order_numbers" /> <PropertyRef Name="customer_name" /> </Key> 

严重的是,不要做这个错误。 让我们说,即使不应该有重复,不知怎的,两行进入我的系统具有相同的订单号和客户名称。 Whooops! 这就是我不使用密钥! 所以我使用entity framework删除一个。 因为我知道重复是今天唯一的命令,我这样做:

 var duplicateOrder = myModel.orders.First(x => x.order_date == DateTime.Today); myModel.orders.Remove(duplicateOrder); 

你猜怎么了? 我刚刚删除了重复和原来的! 这是因为我告诉entity frameworkorder_number / cutomer_name是我的主键。 所以当我告诉它删除duplicateOrder时,它在后台执行的操作如下所示:

 DELETE FROM orders WHERE order_number = (duplicateOrder's order number) AND customer_name = (duplicateOrder's customer name) 

有了这个警告,你现在应该好好走了!

如果数据模型过期,也会发生这种情况。

希望这会拯救别人无奈:)

我得到了同样的错误信息,但在我的scheme中,我试图使用PJT(Pure Join Table)来更新从多对多关系派生的实体。

从阅读其他post,我想我可以通过添加一个额外的PK字段到连接表来修复它…但是,如果您添加一个PK列连接表,它不再是一个PJT,你失去了所有的entity framework的优势,如实体之间的自动关系映射。

所以在我的情况下,解决scheme是改变数据库上的连接表来做一个包括外部ID列的两个PK。

如果你的表没有主键,在这种情况下表是“只读”,并且db.SaveChanges()命令总是会带来一个错误

所以它的真实,只需添加一个主键

注意:当你从数据库更新你指向正确的数据库的EF图时,在我的情况下,连接string指向本地数据库,而不是最新的开发数据库,​​学生错误我知道,但我想发布这个,因为它可以是非常令人沮丧,如果你确信你已经添加了主键,你仍然得到相同的错误

我遇到过同样的问题。 正如这个线程所说,我的表没有PK,所以我设置了PK并运行了代码。 但不幸的是错误又来了。 接下来我做了什么,删除了数据库连接(删除解决scheme资源pipe理器的模型文件夹中的.edmx文件)并重新创build它。 错过了之后。 感谢大家分享你的经验。 它节省了大量的时间。

我遇到了这个问题,因为我从一个现有的数据库(由别人devise,我在这里松散地使用术语“devise”)生成我的EDMX。

原来,桌子上没有任何钥匙。 EF正在生成具有多个键的模型。 我不得不去在SQL数据库表中添加一个主键,然后在VS中更新我的模型。

这为我修好了。

添加主键也适用于我!

一旦完成,以下是如何更新数据模型而不删除它 –

右键单击edmx实体devise器页面,然后select“从数据库更新模型”。

我有完全相同的问题,不幸的是,添加主键不能解决问题。 所以这里是我如何解决我的:

  1. 确保你有一个primary key在桌子上,所以我改变我的表,并添加一个主键。
  2. Delete the ADO.NET Entity Data Model (edmx文件),用于映射和连接我的数据库。
  3. Add again a new file of ADO.NET Entity Data Model来连接我的数据库和映射我的模型属性。
  4. Clean and rebuild the solution.

问题解决了。

只需将一个主键添加到您的表中,然后重新创build您的EF