首页 文章

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

提问于
浏览
469

我正在使用.net 3.5的Entity Framework 1 .

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

var RoomDetails = context.Rooms.ToList();

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

我尝试这样做时收到此错误:

context.SaveChanges();

我收到错误:

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

我正在对上下文进行大量更新而没有任何问题,只有在我尝试更新此特定实体时才会这样做 .

我所有的搜索都显示了同样的事情,即我正在尝试更新的实体上没有声明主键 . 但是,我确实有一个主键声明...

18 回答

  • 0

    我遇到过同样的问题 . 正如这个帖子所说,我的表没有PK,所以我设置PK并运行代码 . 但不幸的是,错误又来了 . 我接下来做的是删除数据库连接(删除解决方案资源管理器的Model文件夹中的.edmx文件)并重新创建它 . 之后错误消失了 . 感谢大家分享您的经验 . 它节省了大量时间 .

  • 50

    我只需要从模型中删除表格并再次更新模型,将表格带回来 . 我猜主键是在将表拉入模型后创建的 .

  • 1

    so its true, just add a primary key

    注意:请确保当你're updating your EF diagram from the database that you'指向 right 数据库时,在我的情况下连接字符串指向本地数据库而不是最新的Dev DB,我知道小学生错误,但我想发布这个因为如果您添加了主键并且仍然遇到相同的错误,那会非常令人沮丧

  • 37

    UPDATE: 我've gotten a few upvotes on this lately, so I figured I' d让人们知道我给出的建议是不是已经意识到你可以做的最好的东西是通过反向代码优先做的 . 关于如何做到这一点,有一些很好的文章 . 只需按照它们,然后当您想要添加密钥时,使用数据注释即可 .

    例如,假设我知道我的表 Orders ,而它没有't have a primary key, is assured to only ever have one order number per customer. Since those are the first two columns on the table, I' d设置代码的第一个类看起来像这样:

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

    通过这样做,你基本上假装EF相信有一个由OrderNumber和Customer组成的聚类键 . 这将允许您在无密钥表上执行插入,更新等操作 .

    如果你不太熟悉反向Code First,那就去找一个关于Entity Framework Code First的好教程 . 然后在Reverse Code First(使用现有数据库执行Code First)上找到一个 . 然后回到这里再看看我的主要建议 . :)

    Original Answer

    第一:正如其他人所说,最好的选择是在表格中添加一个主键 . 完全停止 . 如果您可以这样做,请不要再进一步阅读 .

    但是,如果你不能,或者只是讨厌自己,那么有一种方法可以在没有主键的情况下完成 .

    就我而言,我正在使用遗留系统(最初在AS400上的平面文件移植到Access,然后移植到T-SQL) . 所以我必须找到一种方法 . 这是我的解决方案 . 以下使用Entity Framework 6.0(编写本文时最新的NuGet)为我工作 .

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

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

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

    • store:Schema="whatever" 更改为 Schema="whatever"

    • 在该行下方找到 <DefiningQuery> 标签 . 它将有一个很大的内容 .

    • 现在你的行应该是这样的:
      <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />

    • 我们还有其他一些需要改变的地方 . 浏览您的文件并找到:
      <EntityType Name="table_name">

    • 在附近你可能会看到一些评论文本警告你它没有识别出主键,因此推断了密钥并且定义是只读表/视图 . 您可以保留或删除它 . 我已经把它删了 .

    • 以下是 <Key> 标签 . 这是实体框架将用于执行插入/更新/删除的内容 . 所以请你确实这样做 . 该标记中的属性(或属性)需要指示唯一可识别的行 . 例如,假设我知道我的表 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);
    

    你猜怎么着?我刚刚删除了副本和原始版本!那是因为我告诉实体框架,order_number / cutomer_name是我的主键 . 所以当我告诉它删除duplicateOrder时,它在后台做的是:

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

    有了那个警告......你现在应该好好的走!

  • 29

    我得到了这个问题,因为我是从现有数据库生成我的EDMX(由其他人设计,我在这里松散地使用术语'设计') .

    结果表没有任何关键 . EF正在生成具有许多多个键的模型 . 我不得不在SQL中向db表添加主键,然后在VS中更新我的模型 .

    那为我修好了 .

  • 80

    请注意,也许你的 Entity have primary key 但是 your table in database doesn't have primary key .

  • 0

    对我来说就是这种情况 . 简单地删除导致另一个错误 . 我按照这篇文章的步骤,除了最后一个 . 为方便起见,我复制了我所遵循的帖子中的4个步骤来解决问题,如下所示:

    • 右键单击edmx文件,选择打开方式,XML编辑器

    • 在edmx:StorageModels元素中找到实体

    • 完全删除DefiningQuery

    • store:Schema="dbo" 重命名为 Schema="dbo" (否则,代码将生成错误,说明名称无效)

  • 18

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

    希望这会拯救别人的挫折:)

  • 6

    设置主键,然后保存表和刷新,然后转到Model.edmx删除表,然后再次 .

  • 0

    我得到了相同的错误消息,但在我的场景中,我试图使用PJT(纯连接表)更新从多对多关系派生的实体 .

    从阅读其他帖子,我想我可以通过在连接表中添加一个额外的PK字段来修复它...但是,如果你将一个PK列添加到连接表,它不再是一个PJT而你丢失所有的实体框架的优点,如实体之间的自动关系映射 .

    因此,在我的情况下,解决方案是更改DB上的连接表以生成包含外部ID列的BOTH的PK .

  • 0

    只需在表中添加一个主键,然后重新创建EF

  • 903

    我遇到了这个问题并认为它是由于我删除了我的表主键上的索引并将其替换为表中某些其他字段的索引而引起的 .

    删除主键索引并刷新edmx后,插入停止工作 .

    我刷新了旧版本的表格,刷新了edmx,一切都恢复了 .

    我应该注意,当我打开EDMX来解决这个问题时,检查是否有定义的主键,有 . 所以上述建议都没有帮助我 . 但刷新主键上的索引似乎有效 .

  • 4

    通常是因为以下原因之一:

    • 实体集从数据库视图映射

    • 自定义数据库查询

    • 数据库表没有主键

    执行此操作后,您可能仍需要在停止获取错误之前在Entity Framework设计器中更新(或者删除实体然后添加它) .

  • 3

    添加主键也适合我!

    完成后,这里是如何更新数据模型而不删除它 -

    右键单击edmx实体设计器页面和“从数据库更新模型” .

  • 1

    我有完全相同的问题,遗憾的是,添加主键并不能解决问题 . 所以这就是我如何解决我的问题:

    • 确保表格上有 primary key ,因此我更改了表格并添加了主键 .

    • Delete the ADO.NET Entity Data Model (edmx文件)我用来映射和连接我的数据库 .

    • Add again a new file of ADO.NET Entity Data Model 连接我的数据库并映射我的模型属性 .

    • Clean and rebuild the solution.

    问题解决了 .

  • 0

    在XML编辑器中打开您的.edmx文件,然后从Tag中删除标签,并将store:Schema =“dbo”更改为Schema =“dbo”并重建解决方案,现在错误将解决,您将能够保存数据 .

  • 0

    如果您的表没有主键,可能会发生错误,在这种情况下表是“只读”,db.SaveChanges()命令总是会带来错误

  • 2

    只需向表中添加主键即可 . 而已 . 问题解决了 .

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

相关问题