更新:私は最近これについていくつかの賛成票を得たので、私が以下に与えるアドバイスが最善ではないことを人々に知らせたいと思った。最初に古いキーレスデータベースで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の最新)を使用して私に役立ちました。
ソリューションエクスプローラーで.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が挿入/更新/削除を行うために使用するものです。だからあなたがこの権利を確実にしてください。そのタグのプロパティ(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)
そしてその警告があれば...あなたは今行く準備ができているはずです!