ASP.NET MVC 3アプリケーションでコードファーストアプローチを使用し、モデル内のすべての整数主キー(public int Id { get; set; }
)は、デフォルトで自動インクリメントのIDとして設定されます。これを無効にして、主キーの整数を手動で入力する方法を有効にする方法は?
実際の状況では、Id
整数には特別な意味があるので、作成時に選択可能にし、後で編集できるようにします。作成時に整数が指定されていない場合、自動インクリメントされるのが理想的です。そうでない場合は、指定された値が使用されます。しかし、編集可能なプライマリフィールドが私の主なニーズです。 ASP.NET MVC 3でこれをエレガントに行う方法はありますか?
次のデータ注釈オプションを使用します。
[System.ComponentModel.DataAnnotations.KeyAttribute()]
[System.ComponentModel.DataAnnotations.DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]
FluentMappingを使用できます:
modelBuilder.Entity<*entityname*>().Property(m => m.*fieldname*)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
EntityFramework Core 2.0でFluent APIを使用する場合は、次のように記述します。
modelBuilder.Entity<*myEntity*>()
.Property(e => e.*myFieldname*)
.ValueGeneratedNever();
属性を使用:
public class MessageSubject
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
public string Title { get; set; }
public string Comment { get; set; }
public bool BuildIn { get; set; }
}
最新の承認済みEntityFramework.dllバージョン5.0.0をインストールしました。
ただし、v4.0.30319のランタイムバージョンと4.4.0.0のバージョンがあるため、半分の時間で混乱しますが、検索で参照したWebサイトからは確実です(「パッケージマネージャーVS「ツール|ライブラリパッケージマネージャー|パッケージマネージャーコンソール」内のメニューからアクセスし、「PM>」プロンプトで入力する「コンソール」。「インストールパッケージEntityFramework [オプション:最新のプレリリースのバージョン番号または-Pre (ベータ版)] ")5.0.0でした。
...、使用できる属性「System.CompnentModel.DataAnnotations.DatabaseGenerated(Computed、Identity or None)(以前のバージョン)または[...]。Schema.DatabaseGenerated(最新バージョン)」があります。したがって、この属性を使用するか、上記のように流ideaなマッピングアイデアを使用し(William Haack(Remo Gloorによる編集))、最初にコードを作成しない場合(生産を変更する場合)、上記の(Adam Tuliperによる) 1回限りのスクリプトを実行して、ID挿入をオフにします。さらに、IDを指定しない場合は、コードでテーブルのMAX(ID)+ 1を取得する(およびマルチユーザー環境での同時実行の問題に留意する)か、トリガーでID挿入をシミュレートできます。あるいは、式のように穴を埋めたい場合は、挿入された行をインターセプトしてID列が設定されているかどうかを確認することで、おそらくトリガーでこれを行うことができます。そうでない場合は、挿入を続行し、最初に値を設定します。穴を塞ぐアプローチの1つは、そのトリック(覚えていないWebサイトで見たので、ここでは少し推測します)を使用することです。テーブルに行番号の単一列を使用して、最初に使用可能な未使用のID番号を検索します(つまり、ターゲットテーブルのメンバーではない最初の行番号を検索します)。
SQL Server 2005以降:
CREATE TRIGGER updInsYourTable_PlugHolesOnIDIfNull
ON YourTable
FOR update, insert AS
BEGIN
DECLARE @ID INT
SELECT @ID = ID FROM INSERTED
IF @ID IS NULL
BEGIN
;WITH CTE_StagedNumbers AS
(
SELECT ROW_NUMBER() OVER (ORDER BY o.object_id) AS NextFreeIdentity
FROM ( SELECT object_id FROM sys.objects
-- UNION ALL
-- SELECT object_id FROM sys.objects
/* NB: Here if sys.objects is not larger enough say on a small schema
configured database then use a different table otherwise you can
always union all on the same table as many times as you want to
double, triple etc. its size. */
) o
)
UPDATE YourTable
SET ID = (
SELECT TOP 1 NextFreeIdentity
FROM CTE_StagedNumbers
WHERE NextFreeIdentity NOT IN (SELECT ID FROM YourTable)
)
WHERE ID IS NULL
END
END
GO
CTE_StagedNumbersは必要ありません。強調のためだけにあり、主なトリックは必ずしも行番号の設定ではありませんが、1つの整数だけで永続的なステージングテーブル(たとえばStagedNumbers)を設定する場合自動識別のない列(たとえば、NextFreeIdentity INT NOT NULL PRIMARY KEY)、(脇:NB:ID列のYourTable定義は、afterトリガーを使用しているため、nullを受け入れる必要があります)上記の手法では、CTEを完全に削除し、最終選択のCTE_StagedNumbersをStagedNumbersに置き換えます。これが最も効率的です。
これがデータベースのIDフィールドである場合は禁止です。データベース側でID挿入をオフに設定することでできますが、レコードを一括挿入しない限り、実行することはできません。これをIDとして使用したくない場合は、その列のDBでIDオプションをfalseに設定します。