EntitySetを更新できません-DefiningQueryがあり、<UpdateFunction>要素が存在しないため


534

Entity Framework 1と.net 3.5を使用しています。

私はこのような簡単なことをしています:

var roomDetails = context.Rooms.ToList();

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

実行しようとすると、このエラーが発生します。

 context.SaveChanges();

エラーが発生します:

EntitySetを更新できません-DettingQueryがあり、現在の操作をサポートする<ModificationFunctionMapping>要素に<UpdateFunction>要素が存在しないためです。

私はコンテキストで多くの更新を行っており、問題はありません。それは、この特定のエンティティを更新しようとしたときだけです。

私が検索したすべての結果は同じで、更新しようとしているエンティティで宣言されている主キーがないことがわかります。しかし、悲しいかな、私は主キーを宣言しています...


61
間違えました。テーブルに主キーセットがありませんでした。お時間をいただきありがとうございます。ご不便おかけしてすみません!
iKode 2011

1
たまたま私に起こった-おそらく主キーで1000のテーブルを作成し、1つを忘れた-例外メッセージはあまり役に立たない
Peter Munnings

1
優秀な。テーブルに主キーを追加するのを忘れていました。注意してみましょう)
AEMLoviji '11

回答:


1024

これは通常、次のいずれかの理由で発生します。

  • エンティティセットはデータベースビューからマッピングされます
  • カスタムデータベースクエリ
  • データベーステーブルに主キーがありません

エラーが発生しなくなる前に、Entity Frameworkデザイナで更新する(またはエンティティを削除してから追加する)必要がある場合があります。


2
問題が解決しない場合は、store:SchemaをそのEntitySetのスキーマのみに変更してください。
Geoff

53
次に、EFデザイナーでは更新が正しく機能しないため、エンティティを削除して再作成します。
Suncat2000 2013

48
PKが答えでした。ありがとう!
nrod 2013

1
データベースに主キーを追加した後、EFデザイナーでの更新はうまく機能しました。EF 5.0および.net 4.0の使用
StillLearnin 2013

1
こっちも一緒 !Thx ...テーブルを削除してEFに追加し直す必要がありました
ajzeffer

90

テーブルに主キーを追加するだけです。それでおしまい。問題が解決しました。

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

13
.edmxファイルの「データベースからモデルを更新」をクリックするのを忘れないでください
Bashar Abu Shamaa '20

@BasharAbuShamaaこの答えはその詳細なしでは無効です。
Kehlan Krumme、2018年

66

これが私の場合です。単に削除すると、別のエラーが発生しました。私は最後のものを除いて、この投稿のステップに従いました。便宜上、問題を解決するためにフォローした投稿から4つのステップを次のようにコピーしました。

  1. edmxファイルを右クリックして、XMLエディターで開くを選択します。
  2. edmx:StorageModels要素でエンティティを見つけます
  3. DefiningQueryを完全に削除します
  4. の名前store:Schema="dbo"を変更しますSchema="dbo"(それ以外の場合、コードは名前が無効であることを示すエラーを生成します)

どうもありがとうございました。これが私の問題を修正したものです。これはEFで修正されていないことにかなり不安を感じます。そして、あなたがこれを理解したことはかなり驚くべきことです!
自転車デイブ

エンティティを削除して、もう一度追加してみました。再コンパイル。クリーニング。これ以外は何もうまくいきませんでした。
Vintastic

1
これで私の問題は解決しましたが、どのようにして回答を思いついたのか、そしてあなたの提案がなぜ問題を解決したのかわかりません。
swcraft 2016

データベースモデルを更新する必要がある場合はどうなりますか?「データベースからモデルを更新」を実行したところ、モデルがまったく使用できなくなりました。元に戻してやり直す必要がありました。これを回避する方法はありますか?
ゲイリー

それは本当に奇妙な問題です。それを回避するためにこの問題がどのように発生するかについての情報はありますか?それにもかかわらず、それは助けになりました
r3dst0rm 2018年

41

ただ、それは多分あなたの注意のエンティティが持つプライマリキーが、データベース内にあなたのテーブルがありません主キーを


1
データベーステーブルを変更できない場合の対処方法
Kai Hartmann

主キーを持つようにDBテーブルを変更できる場合、コードジェネレーターは同じ間違いを犯しなくなり、EFからキーを削除すると他の多くの問題が発生します。
Chris Schaller

30

更新:私は最近これについていくつかの賛成票を得たので、私が以下に与えるアドバイスが最善ではないことを人々に知らせたいと思った。最初に古いキーレスデータベースでEntity Frameworkをいじくり始めたので、FAR BYで実行できる最善のことは逆コードファーストで実行することに気づきました。これを行う方法については、いくつかの優れた記事があります。それらに従うだけで、それにキーを追加したい場合は、データ注釈を使用してキーを「偽造」します。

たとえば、テーブルOrdersに主キーがないのに、顧客ごとに1つの注文番号しか持てないことがわかっているとしましょう。これらはテーブルの最初の2つの列なので、コードの最初のクラスを次のように設定します。

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

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

これを行うことで、EFをだまして、OrderNumberとCustomerで構成されるクラスター化されたキーがあると信じ込ませます。これにより、キーレステーブルで挿入、更新などを行うことができます。

コードファーストを逆にするのに慣れていない場合は、Entity Frameworkコードファーストのチュートリアルをご覧ください。次に、リバースコードファースト(既存のデータベースでコードファーストを実行しています)を探します。次に、ここに戻って、私の重要なアドバイスをもう一度見てください。:)

元の回答

最初:他の人が言ったように、最良のオプションはテーブルに主キーを追加することです。フルストップ。これができる場合は、これ以上読み進めないでください。

しかし、それができない場合、または単に自分を憎む場合は、主キーなしでそれを行う方法があります。

私の場合、私はレガシシステム(元々はAccessに移植され、次にT-SQLに移植されたAS400のフラットファイル)で作業していました。だから私は方法を見つけなければなりませんでした。これが私の解決策です。以下は、Entity Framework 6.0(この記事の執筆時点でのNuGetの最新)を使用して私に役立ちました。

  1. ソリューションエクスプローラーで.edmxファイルを右クリックします。「アプリケーションから開く...」を選択し、「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. その行の下を見て、<DefiningQuery>タグを見つけます。それには大きな古いselectステートメントが含まれます。タグを削除すると、そのコンテンツが表示されます。

  6. これで、行は次のようになります。
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />

  7. 他に何か変更することがあります。ファイルを調べて、これを見つけます。
    <EntityType Name="table_name">

  8. 近くには、主キーが識別されていないため、キーが推測され、定義が読み取り専用のテーブル/ビューであることを警告するコメント付きのテキストがおそらく表示されます。そのままにすることも削除することもできます。削除しました。

  9. 以下は<Key>タグです。これは、Entity Frameworkが挿入/更新/削除を行うために使用するものです。だからあなたがこの権利を確実にしてください。そのタグのプロパティ(1つまたは複数)は、一意に識別可能な行を示す必要があります。たとえば、テーブルordersに主キーがないのに、顧客ごとに1つの注文番号しか持てないことがわかっているとしましょう。

だから私のものは次のようになります:

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

真剣に、これを間違えないでください。重複があり得ないとしても、どういうわけか、同じ注文番号と顧客名の2つの行がシステムに入るとしましょう。おっと!それは私がキーを使用しないことで得られるものです!そこで、Entity Frameworkを使用して削除します。複製が今日の唯一の注文であることを知っているので、これを行います。

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)

そしてその警告があれば...あなたは今行く準備ができているはずです!


問題の同じ解決策を見つけた後にこの答えを見つけました。間違いなく正解です。他の回答で述べられているように主キーを定義するだけでは、多くの場合役に立ちません。
Obl Tobl 2014年

19

これは、データモデルが古い場合にも発生する可能性があります。

うまくいけば、これは他の誰かの欲求不満を救うでしょう:)


6

同じエラーメッセージが表示されましたが、私のシナリオでは、PJT(Pure Join Table)を使用して多対多の関係から派生したエンティティを更新しようとしました。

他の投稿を読んで、結合テーブルに追加のPKフィールドを追加することで修正できると思いました...ただし、結合テーブルにPK列を追加すると、それはPJTではなくなり、すべてを失いますエンティティ間の自動関係マッピングのようなエンティティフレームワークの利点。

したがって、私の場合の解決策は、DBの結合テーブルを変更して、外部ID列の両方を含むPKを作成することでした。


これは、EDMXの生成が常に機能してきた方法ですか?純粋な結合テーブルでPKを必要としないCode Firstを使用することに慣れています。
Michael Hornfeck 2014年

4

テーブルに主キーがない場合、エラーが発生する可能性があります。この場合、テーブルは「読み取り専用」であり、db.SaveChanges()コマンドは常にエラーを引き起こします


4

主キーを設定してからテーブルを保存して更新し、Model.edmxに移動してテーブルを削除してからもう一度取得します。


3

だから本当です、主キーを追加するだけです

注:適切なデータベースを指しているデータベースからEFダイアグラムを更新しているときは、接続文字列が最新のDev DBではなく、ローカルDBを指していることを確認してください。エラー私は知っていますが、主キーを追加したと確信していても同じエラーが発生する場合は非常にイライラする可能性があるため、これを投稿しました


2

同じ問題がありました。このスレッドが言ったように、私のテーブルにはPKがなかったので、PKを設定してコードを実行しました。しかし、残念ながら再びエラーが発生しました。次に行ったのは、DB接続を削除し(ソリューションエクスプローラーのモデルフォルダーにある.edmxファイルを削除)、それを再作成しました。その後エラーが発生しました。皆さんの経験を共有してくれてありがとう。それは多くの時間を節約します。


1

既存のデータベースからEDMXを生成していたため、この問題が発生していました(誰かが設計したもので、ここでは「設計」という用語を大まかに使用しています)。

テーブルにはまったくキーがありませんでした。EFは、多数の複数のキーを持つモデルを生成していました。SQLでdbテーブルに主キーを追加し、VSでモデルを更新する必要がありました。

これで解決しました。


1

これは新しい答えではありませんが、テーブルの主キーを設定する方法がわからない場合に役立ちます。これを新しいクエリで使用して実行します。これにより、UniqueID列が主キーとして設定されます。

USE [YourDatabaseName]
GO

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

1

ここに画像の説明を入力してください

私の場合、テーブルの主キーを定義するのを忘れていました。したがって、図に示すように割り当て、.edmxファイルの「データベースからモデルを更新」からテーブルを更新します。それが役に立てば幸い!


0

主キーの追加も私にとってはうまくいきました!

それが完了したら、データモデルを削除せずに更新する方法を次に示します-

edmxエンティティデザイナーページを右クリックし、[データベースからモデルを更新]をクリックします。


0

まったく同じ問題がありましたが、残念ながら、主キーを追加しても問題は解決しません。だからここに私が私の問題を解決する方法があります:

  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.

問題が解決しました。



0

モデルからテーブルを削除し、モデルを再度更新してテーブルを元に戻す必要がありました。テーブルがモデルに取り込まれた後に主キーが作成されたと思います。


0

この問題が発生し、テーブルの主キーのインデックスを削除し、それをテーブルの他のいくつかのフィールドのインデックスに置き換えたために発生したと考えています。

主キーインデックスを削除してedmxを更新した後、挿入が機能しなくなりました。

テーブルを古いバージョンに更新し、edmxを更新すると、すべてが再び機能します。

この問題のトラブルシューティングを行うためにEDMXを開いたときに、主キーが定義されているかどうかを確認していたので注意してください。したがって、上記の提案のどれも私を助けていませんでした。しかし、主キーのインデックスを更新すると機能するように見えました。


0

XMLエディターで.edmxファイルを開き、タグからタグを削除し、store:Schema = "dbo"をSchema = "dbo"に変更してソリューションを再構築すると、エラーが解決し、データを保存できるようになります。


0

私の状況では、.edmxファイルを更新する最初の答えが最も効果的であることがわかりました。データベースから更新されるたびにモデルを変更することにあまり満足していませんでした。エンティティが新しく生成されるように、モデルが変更された後に自動的に呼び出される追加のテキストテンプレートファイルを作成したのはそのためです。このコメントでここに投稿します。これを機能させるには、{モデル名} .something.ttのような名前を付けて、.edmxフォルダーと同じフォルダーに保存してください。{モデル名} .NonPkTables.ttという名前にしました。2行目の無効なファイル拡張子定義のため、それ自体ではファイルを生成しません。お気軽にご利用ください。

<#@ 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);
#>

-1

多対多のリレーションを持つテーブルにレコードを挿入すると、同じエラーメッセージが表示されました。私のデータベーススキーマは:

Student (Id , Name)
Course (Code , Title),
Student-Course (Student_ID, Course_Code)

学生コースは主キー持ち同上とコードをそれぞれ表ながら、学生、コースは学生とコースのテーブルにマッピングされた2つの外部キーがあります。

論理的には、スキーマは正しいですが、すべてのテーブルに主キーがあるはずなので、データベースでミスをしていました。

Student-Courseの SQL定義は次のとおりです。

CREATE TABLE [dbo].[Student-Course] (
    [StudentID]  VARCHAR (12) NOT NULL,
    [CourseCode] VARCHAR (10) NOT NULL,
    CONSTRAINT [FK_Student-Course_ToCourse] FOREIGN KEY ([Course_Code]) REFERENCES [dbo].[Course] ([Code]) ON DELETE CASCADE,
    CONSTRAINT [FK_Student-Course_ToStudent] FOREIGN KEY ([Student_ID]) REFERENCES [dbo].[Student] ([Id]) ON DELETE CASCADE
);

外部キーのペアをこのテーブルの主キーにして、次のように更新しました。

CREATE TABLE [dbo].[Student-Course] (
    [StudentID]  VARCHAR (12) NOT NULL,
    [CourseCode] VARCHAR (10) NOT NULL,
    CONSTRAINT [PK_Student-Course] PRIMARY KEY CLUSTERED ([Student_ID] ASC, [Course_Code] ASC),
    CONSTRAINT [FK_Student-Course_ToCourse] FOREIGN KEY ([Course_Code]) REFERENCES [dbo].[Course] ([Code]) ON DELETE CASCADE,
    CONSTRAINT [FK_Student-Course_ToStudent] FOREIGN KEY ([Student_ID]) REFERENCES [dbo].[Student] ([Id]) ON DELETE CASCADE
);

一部の人の問題が解決することを願っています。


この質問にはすでに答えが多すぎます。また、ほとんどのそれぞれの答えは、「主キーを追加します」と述べている1は、多対多の関係でそれをしません。
ガートアーノルド

あなたは正しいですが、一部の人々は3番目のテーブルに追加の主キーIDを追加しますが、これは良いアプローチではありません。
Summar Raja

他の答えも言うように。
Gert Arnold
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.