Entity Framework 1を.net 3.5で使用しています。
私はこのような簡単なことをしています:
var RoomDetails = context.Rooms.ToList();
foreach (var Room in Rooms)
{
Room.LastUpdated = DateTime.Now;
}
私がやろうとすると私はこのエラーを得ています:
context.SaveChanges();
私はエラーが出ます:
EntitySetを更新できません - これはDefiningQueryを持ち、現在の操作をサポートするための<ModificationFunctionMapping>要素に<UpdateFunction>要素が存在しないためです。
私は文脈で多くの更新をしていて、何の問題もありません、それは私がこの特定の実体を更新しようとするときだけです。
私が検索しようとしていることはすべて同じことを示しています。更新しようとしているエンティティに主キーが宣言されていないことです。しかし、あいにく、私は宣言された主キーを持っています...
これは通常、次のいずれかの理由により発生します。
そうしても、エラーが発生するのを止める前に、Entity Frameworkデザイナで更新する(またはエンティティを削除して追加する)必要があるかもしれません。
テーブルに主キーを追加するだけです。それでおしまい。問題が解決しました。
ALTER TABLE <TABLE_NAME>
ADD CONSTRAINT <CONSTRAINT_NAME> PRIMARY KEY(<COLUMN_NAME>)
これは私の場合です。単純に削除すると別のエラーが発生しました。私は最後のものを除いてこの記事のステップに従った。あなたの便宜のために、私は次のように問題を解決するために私が従った投稿から4つのステップをコピーしました:
store:Schema="dbo"
の名前をSchema="dbo"
に変更します(そうでない場合、コードは名前が無効であるというエラーを生成します)ちょうどあなたのEntity have primary key _でもデータベースのあなたのテーブル は持っていません primary keyだけであることに注意してください。
更新: 最近これについていくつかの支持を得たので、私が下に与えるアドバイスが最良ではないことを人々に知らせたいと思った。私はもともと古いキーレスデータベースでEntity Frameworkを使うことから悩み始めたので、私はあなたがFARでできる最善のことはリバースコードファーストでそれをすることであることを理解するようになりました。これを行う方法についていくつかの良い記事があります。それらに従ってください、そしてあなたがそれにキーを追加したいときは、キーを「偽造」するためにデータ注釈を使用してください。
たとえば、テーブル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のコードファーストの優れたチュートリアルを探してください。次に、Reverse Code First(既存のデータベースでCode Firstを実行している)で検索します。それからここに戻って、私の重要なアドバイスをもう一度見てください。 :)
オリジナルの回答 :
まず、他の人が言っているように、最善の選択肢はテーブルに主キーを追加することです。フルストップあなたがこれを行うことができるならば、もう読んではいけない。
しかし、あなたができない、あるいは単に自分を憎むのであれば、主キーなしでそれを行う方法があります。
私の場合、私はレガシーシステムで作業していました(当初は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>
タグを見つけてください。それはその中に大きな古い 'select文を持つでしょう。タグを削除するとその内容です。
これで、あなたの行は次のようになります。<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />
他にも変更があります。ファイルを調べて、これを見つけます。<EntityType Name="table_name">
近くには、主キーが識別されていないことを警告するコメント付きのテキストが表示される可能性があるので、キーは推測され、定義は読み取り専用のテーブル/ビューです。それを残すことも削除することもできます。削除しました。
以下は<Key>
タグです。これがEntity Frameworkが挿入/更新/削除を行うために使用しようとしているものです。 SOこの権利があることを確認してください。そのタグのプロパティは、一意に識別可能な行を示す必要があります。たとえば、テーブル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);
何だと思う?複製とオリジナルの両方を削除しました。これは、order_number/cutomer_nameが主キーであることをEntity Frameworkに伝えたためです。それで私がduplicateOrderを削除するように言ったとき、それがバックグラウンドでしたことは以下のようなものでした:
DELETE FROM orders
WHERE order_number = (duplicateOrder's order number)
AND customer_name = (duplicateOrder's customer name)
そしてその警告で...あなたは今行ってもいいでしょう!
データモデルが古くなっている場合も同様です。
うまくいけば、これは他の誰かの欲求不満を救うでしょう:)
同じエラーメッセージが表示されましたが、私のシナリオでは、PJT(Pure Join Table)を使用して多対多の関係から派生したエンティティを更新しようとしていました。
他の記事を読んで、結合テーブルに追加のPKフィールドを追加することで解決できると思いました。ただし、結合テーブルにPK列を追加すると、それはPJTではなくなり、すべてが失われます。エンティティ間の自動関係マッピングのようなエンティティフレームワークの利点。
したがって、私の場合の解決策は、外部ID列の両方を含むPKを作成するようにDB上の結合テーブルを変更することでした。
テーブルに主キーがない場合、エラーが発生する可能性があります。この場合、テーブルは「読み取り専用」であり、db.SaveChanges()コマンドは常にエラーを引き起こします。
そのため、主キーを追加するだけです
注:右データベースを指しているデータベースからEFダイアグラムを更新するときは、接続文字列が指していることを確認してください最新のDev DBではなくローカルDBに、私は知っている少年のエラーがありますが、主キーを追加したと確信している場合は非常にイライラする可能性があるため、これを投稿したかったです同じエラー
主キーを設定してからテーブルを保存し、更新してからModel.edmxテーブルの削除に移動して再度取得します。
私は同じ問題を抱えていました。このスレッドが言ったように、私のテーブルにはPKがありませんでしたので、PKを設定してコードを実行しました。しかし、残念ながら、エラーがまた起こりました。次に行ったのは、DB接続を削除し(Solution ExplorerのModelフォルダーにある.edmxファイルを削除し)、それを再作成したことです。その後エラーがなくなりました。あなたの経験を共有してくれてありがとう。それは多くの時間を節約します。
私がこの問題を抱えていたのは、私がEDMXを既存のデータベース(他の誰かによって設計されたもの)から生成していたためです。
テーブルにはキーがまったくないことがわかりました。 EFは多数の複数のキーを持つモデルを生成していました。 SQLでdbテーブルに主キーを追加してから、VSで自分のモデルを更新する必要がありました。
それは私のためにそれを修正しました。
これは新しい答えではありませんが、自分のテーブルに主キーを設定する方法がわからない場合に役立ちます。これを新しいクエリで使用して実行します。これはUniqueID列を主キーとして設定します。
USE [YourDatabaseName]
GO
Alter table [dbo].[YourTableNname]
Add Constraint PK_YourTableName_UniqueID Primary Key Clustered (UniqueID);
GO
モデルからテーブルを削除し、モデルを更新してテーブルを元に戻すだけでした。テーブルがモデルに取り込まれた後に主キーが作成されたと思います。
私はまったく同じ問題を抱えていましたが、残念ながら主キーを追加しても問題は解決されません。それで、これが私がどうやって解決するかです:
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.
問題が解決しました。
主キーを追加することも私のために働きました!
それが行われたら、これを削除せずにデータモデルを更新する方法は次のとおりです -
Edmxエンティティデザイナページを右クリックし、[データベースからモデルを更新]をクリックします。
XMLエディタで.edmxファイルを開き、Tagからtagを削除してstore:Schema = "dbo"をSchema = "dbo"に変更してソリューションを再構築するとエラーが解決され、データを保存できるようになります。
テーブルに主キーを追加してEFを再作成するだけです。
この問題が発生したのは、テーブルの主キーのインデックスを削除し、それをテーブル内の他のフィールドのインデックスに置き換えたためであると考えられます。
主キーインデックスを削除してedmxを更新した後、挿入が機能しなくなりました。
テーブルを古いバージョンに更新し、edmxを更新したところ、すべてうまくいきました。
この問題を解決するためにEDMXを開いたときに、主キーが定義されているかどうかを確認する必要がありました。だから上記の提案のどれも私を助けていなかった。しかし、主キーのインデックスを更新するとうまくいくようです。