【问题标题】:Unable to update the EntitySet - because it has a DefiningQuery and no <UpdateFunction> element exist无法更新 EntitySet - 因为它有一个 DefiningQuery 并且不存在 <UpdateFunction> 元素
【发布时间】:2011-11-26 21:07:15
【问题描述】:

我正在使用带有 .net 3.5 的实体框架 1。

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

var roomDetails = context.Rooms.ToList();

foreach (var room in roomDetails)
{        
   room.LastUpdated = DateTime.Now;
}

当我尝试这样做时出现此错误:

 context.SaveChanges();

我得到错误:

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

我正在对上下文进行大量更新并且没有任何问题,只是当我尝试更新这个特定实体时。

我的所有搜索都显示相同的内容,即在我尝试更新的实体上没有声明主键。但是,唉,我确实声明了一个主键...

【问题讨论】:

  • 我搞错了,桌子上没有设置主键,谢谢你的时间!给您带来的不便深表歉意!
  • 刚刚发生在我身上 - 可能用主键创建了 1000 个表,但忘记了一个 - 异常消息没有多大帮助
  • 优秀。真的我忘了给表添加主键。让我们尽量小心)

标签: c# asp.net .net entity-framework primary-key


【解决方案1】:

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

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

执行此操作后,您可能仍需要在实体框架设计器中进行更新(或者删除实体然后添加它),然后才能停止收到错误。

【讨论】:

  • 如果您仍然遇到问题,请确保也将 store:Schema 更改为该 EntitySet 的 Schema。
  • 然后删除并重新创建实体,因为更新在 EF 设计器中无法正常工作。
  • PK 就是答案。谢谢!
  • 在将主键添加到数据库后,EF 设计器中的更新对我来说效果很好。使用 EF 5.0 和 .net 4.0
  • 这里也一样! Thx ...必须删除表并重新添加到 EF 才能让它接受
【解决方案2】:

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

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

【讨论】:

  • 别忘了点击 .edmx 文件上的“从数据库更新模型”
  • @BasharAbuShamaa 如果没有该详细信息,此答案无效。
【解决方案3】:

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

  1. 右击edmx文件,选择打开方式,XML编辑器
  2. 在 edmx:StorageModels 元素中找到实体
  3. 完全删除 DefiningQuery
  4. store:Schema="dbo"重命名为Schema="dbo"(否则代码会产生错误提示名称无效)

【讨论】:

  • 非常感谢 - 这正是解决我的问题的原因。相当令人不安的是,这还没有在 EF 中得到解决。而且,你能想到这一点真是太神奇了!
  • 我尝试删除实体并重新添加它。重新编译。打扫。除了这个,没有什么对我有用。
  • 这解决了我的问题,但我不知道你是怎么想出答案的,为什么你的建议解决了这个问题。
  • 如果需要更新数据库模型怎么办?我做了一个“从数据库更新模型”,它让我的模型完全无法使用。我不得不撤消并重新开始。如果有办法解决这个问题?
  • 这是一个非常奇怪的问题。是否有任何关于如何发生此问题以避免它的信息?尽管如此 - 它有帮助
【解决方案4】:

请注意,也许您的实体主键您在数据库中的表没有主键

【讨论】:

  • 无法更改数据库表如何克服?
  • 如果您可以将数据库表更改为具有主键,那么代码生成器将不再犯同样的错误,从 EF 中删除键会导致许多其他问题。
【解决方案5】:

更新:我最近在这方面得到了一些支持,所以我想我会让人们知道我在下面给出的建议并不是最好的。自从我最初开始在旧的无密钥数据库上做实体框架以来,我已经意识到你能做的最好的事情就是通过反向代码优先来做。有一些关于如何做到这一点的好文章。只需按照它们,然后当您想为其添加密钥时,使用数据注释来“伪造”密钥。

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

    [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)。然后回到这里,再次查看我的关键建议。 :)

原答案

首先:正如其他人所说,最好的选择是向表中添加主键。句号。如果您能做到这一点,请不要继续阅读。

但如果你不能,或者只是讨厌自己,有一种方法可以在没有主键的情况下做到这一点。

就我而言,我使用的是遗留系统(最初是 AS400 上的平面文件,移植到 Access,然后移植到 T-SQL)。所以我必须想办法。这是我的解决方案。以下内容对我使用 Entity Framework 6.0(截至本文撰写时 NuGet 的最新版本)有效。

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

  2. 寻找这样的一行:
    &lt;EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane"&gt;

  3. 从末尾删除store:Name="table_name"

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

  5. 查看该行下方并找到&lt;DefiningQuery&gt; 标记。它将有一个很大的选择语句。删除标签及其内容。

  6. 现在您的线路应该如下所示:
    &lt;EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" /&gt;

  7. 我们还有一些东西要改变。浏览您的文件并找到以下内容:
    &lt;EntityType Name="table_name"&gt;

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

  9. 下面是&lt;Key&gt; 标签。这就是 Entity Framework 将用来执行插入/更新/删除的内容。所以请确保您做对了。该标记中的属性(或多个属性)需要指示唯一可识别的行。例如,假设我知道我的表orders,虽然它没有主键,但可以确保每个客户只有一个订单号。

所以我的看起来像:

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

说真的,不要做错了。假设即使永远不应该有重复,两行以相同的订单号和客户名称进入我的系统。哎呀!这就是我不使用密钥的结果!所以我使用实体框架删除一个。因为我知道副本是今天发出的唯一订单,所以我这样做:

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

你猜怎么着?我刚刚删除了副本和原件!那是因为我告诉 Entity Framework order_number/cutomer_name 是我的主键。因此,当我告诉它删除 duplicateOrder 时,它在后台执行的操作类似于:

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

有了这个警告……你现在应该可以开始了!

【讨论】:

  • 在找到问题的相同解决方案后找到了这个答案。绝对是正确答案!在许多情况下,仅定义其他答案中提到的主键无济于事。
【解决方案6】:

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

希望这可以避免其他人的挫败感:)

【讨论】:

    【解决方案7】:

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

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

    因此,在我的情况下,解决方案是更改数据库上的连接表,以创建包含两个外部 ID 列的 PK。

    【讨论】:

    • 这就是生成 EDMX 一直以来的工作方式吗?我习惯使用 Code First,它不需要在纯连接表上进行 PK。
    【解决方案8】:

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

    【讨论】:

      【解决方案9】:

      设置主键然后保存表并刷新然后去Model.edmx删除表并再次获取。

      【讨论】:

        【解决方案10】:

        确实如此,只需添加一个主键

        注意:请确保当您从指向 right 数据库的数据库中更新 EF 图时,在我的情况下,连接字符串指向本地DB而不是最新的Dev DB,我知道男生错误,但我想发布这个,因为如果你确信你已经添加了主键并且你仍然得到同样的错误,这可能会非常令人沮丧

        【讨论】:

          【解决方案11】:

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

          【讨论】:

            【解决方案12】:

            这不是一个新的答案,但会帮助那些不确定如何为他们的表设置主键的人。在新查询中使用它并运行。这会将 UniqueID 列设置为主键。

            USE [YourDatabaseName]
            GO
            
            Alter table  [dbo].[YourTableNname]
            Add Constraint PK_YourTableName_UniqueID Primary Key Clustered (UniqueID);
            GO
            

            【讨论】:

              【解决方案13】:

              在我的情况下,忘记定义表的主键。因此,如图所示分配并从 .edmx 文件中的“从数据库更新模型”刷新您的表。 希望它会有所帮助!

              【讨论】:

                【解决方案14】:

                我遇到这个问题是因为我从现有数据库(由其他人设计,我在这里松散地使用“设计”一词)生成我的 EDMX。

                原来桌子上没有任何钥匙。 EF 正在生成具有许多多个键的模型。我必须在 SQL 中向 db 表添加一个主键,然后在 VS 中更新我的模型。

                这为我解决了问题。

                【讨论】:

                  【解决方案15】:

                  添加主键也对我有用!

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

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

                  【讨论】:

                    【解决方案16】:

                    不幸的是,我遇到了完全相同的问题,添加主键并不能解决问题。所以这是我的解决方法:

                    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.

                    问题解决了。

                    【讨论】:

                      【解决方案17】:

                      只需向您的表添加一个主键,然后重新创建您的 EF

                      【讨论】:

                        【解决方案18】:

                        我只需要从模型中删除表格并再次更新模型,将表格恢复原状。我猜主键是在将表拉入模型后创建的。

                        【讨论】:

                          【解决方案19】:

                          我遇到了这个问题,我认为这是因为我删除了我的表主键上的索引并将其替换为表中其他一些字段的索引。

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

                          我将表格刷新到旧版本,刷新了 edmx,一切都恢复正常了。

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

                          【讨论】:

                            【解决方案20】:

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

                            【讨论】:

                              【解决方案21】:

                              我发现更新 .edmx 文件的原始答案最适合我的情况。每次从数据库更新模型时,我都对更改模型不太满意。这就是为什么我写了一个额外的文本模板文件,当模型改变后会自动调用它——就像新生成的实体一样。我将其发布在此评论中。 要使其正常工作,请确保将其命名为 {model name}.something.tt,并将其存储在与 .edmx 文件夹相同的文件夹中。我将其命名为 {model name}.NonPkTables.tt。由于第二行中的文件扩展名定义无效,它不会自行生成文件。随意使用。

                              <#@ template language="C#" debug="false" hostspecific="true"#>
                              <#@ output extension="/" #>
                              <#@ assembly name="System.Core" #>
                              <#@ assembly name="System.Data" #>
                              <#@ assembly name="System.Windows.Forms" #>
                              <#@ assembly name="System.Xml" #>
                              <#@ assembly name="System.Xml.Linq"#>
                              <#@ assembly name="%VS120COMNTOOLS%..\IDE\EntityFramework.dll" #>
                              <#@ assembly name="%VS120COMNTOOLS%..\IDE\Microsoft.Data.Entity.Design.dll" #>
                              <#@ import namespace="System" #>
                              <#@ import namespace="System.Windows.Forms" #>
                              <#@ import namespace="System.Linq" #>
                              <#@ import namespace="System.IO" #>
                              <#@ import namespace="System.Collections.Generic" #>
                              <#@ import namespace="System.Xml" #>
                              <#@ import namespace="System.Xml.Linq" #>
                              <#@ import namespace="System.Globalization" #>
                              <#@ import namespace="System.Reflection" #>
                              <#@ import namespace="System.Data.Entity.Core.Metadata.Edm" #>
                              <#@ import namespace="System.Data.Entity.Core.Mapping" #>
                              <#@ import namespace="System.CodeDom" #>
                              <#@ import namespace="System.CodeDom.Compiler" #>
                              <#@ import namespace="Microsoft.CSharp"#>
                              <#@ import namespace="System.Text"#>
                              <#@ import namespace="System.Diagnostics" #>
                              
                              <#
                                  string modelFileName= this.Host.TemplateFile.Split('.')[0] + ".edmx";
                                  string edmxPath = this.Host.ResolvePath( modelFileName );
                              
                                  // MessageBox.Show( this.Host.TemplateFile + " applied." );
                                  var modelDoc = XDocument.Load(edmxPath);
                                  var root = modelDoc.Root;
                                  XNamespace nsEdmx = @"http://schemas.microsoft.com/ado/2009/11/edmx";
                                  XNamespace ns = @"http://schemas.microsoft.com/ado/2009/11/edm/ssdl";
                              
                                  var runtime = root.Elements(nsEdmx + "Runtime").First();
                                  var storageModels = runtime.Elements(nsEdmx + "StorageModels").First();
                                  XNamespace nsStore = @"http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator";
                              
                                  var schema = storageModels.Elements(ns + "Schema").First();
                                  XNamespace nsCustomAnnotation = @"http://schemas.microsoft.com/ado/2013/11/edm/customannotation";
                              
                                  var entityTypes = schema.Nodes().OfType<XComment>().Where(c => c.Value.Contains("warning 6002: The table/view"));
                                  bool changed = false;
                              
                                  foreach (var node in entityTypes)
                                  {
                                      var element = node.ElementsAfterSelf().First();
                                      string entityName = element.Attribute("Name").Value;
                              
                                      // Find EntitySet in EntityContainer.
                                      var entityContainer = schema.Elements(ns + "EntityContainer").First();
                                      var entitySet = entityContainer.Elements(ns + "EntitySet").First(s => s.Attribute("Name").Value == entityName);
                              
                                      // Change "store:Schema" attribute to "Schema" attribute.
                                      var attribute = entitySet.Attribute(nsStore + "Schema");
                              
                                      if (attribute != null)
                                      {
                                          string schemaName = entitySet.Attribute(nsStore + "Schema").Value;
                                          entitySet.Attribute(nsStore + "Schema").Remove();
                                          entitySet.Add(new XAttribute("Schema", schemaName));
                                          changed |= true;
                                      }
                              
                                      // Remove the DefiningQuery element.
                                      var definingQuery = entitySet.Element(ns + "DefiningQuery");
                              
                                      if (definingQuery != null)
                                      {
                                          definingQuery.Remove();
                                          changed |= true;        
                                          Debug.WriteLine(string.Format("Removed defining query of EntitySet {0}.", entityName));
                                      }
                                  }
                              
                                  if (changed)
                                      modelDoc.Save(edmxPath);
                              #>
                              

                              【讨论】:

                                【解决方案22】:

                                我通过删除和重建 EF 项目及其所有类来修复它。请参阅下面的详细信息:

                                我在这个问题上转了一个小时,然后删除了包含错误的 EF 项目,保存了我所有的自定义代码,然后重新构建了整个东西。由于只是生成一个新的 EF 图及其内部代码,这个修复问题的过程大约需要 10 分钟。

                                我怀疑,问题在于生成 EF 类和属性的数据库优先方法在两三个“更新”之后变得有点奇怪。基本上我发现代码行为有问题,去修复数据库表属性,然后更新EF图一次太多了。然后我尝试摆弄代码,但没有成功。

                                重新开始工作。

                                【讨论】:

                                  猜你喜欢
                                  • 2011-01-31
                                  • 2012-09-01
                                  • 1970-01-01
                                  • 2012-11-30
                                  • 2013-02-25
                                  • 1970-01-01
                                  • 2023-04-07
                                  • 2012-01-30
                                  • 2010-12-08
                                  相关资源
                                  最近更新 更多