0

友人が、計算列、Entity Framework、および Breeze に関する問題を報告しました

データベースによって計算された「FullName」列を持つテーブルがあります。新しい を作成するとき、プロパティ値がまったく設定されていない場合でもPerson、Breeze はプロパティ値をサーバーに送信し、新しいインスタンスを挿入しようとするとエラーが発生します。データベースは次の例外をスローします。FullNamePerson

The column "FullName" cannot be modified because it is either a computed column or is the result of a UNION operator.

以下は、SQL テーブル定義の関連部分です。

CREATE TABLE [dbo].[人](
      [ID] [bigint] IDENTITY(1,1) NOT NULL,
      [名前] [varchar](100) NULL,
      [ミドルネーム] [varchar](100) NULL,
      [姓] [varchar](100) NOT NULL,
      [FullName] AS ((([Patient].[LastName]+',') + isnull(' '+[Patient].[FirstName],'')) + isnull(' '+[Patient].[MiddleName] ,'')),
      ...

友人によると、対応する「Code First」クラスは次のようになります。

パブリック クラス Person {
      public int ID {get; 設定;}
      パブリック文字列 FirstName {get; 設定;}
      public string MiddleName {get; 設定;}
      public string LastName {get; 設定;}
      パブリック文字列 FullName {get; 設定;}
      ...
}

この質問への回答は、問題を説明し、解決策を提供します。

4

1 に答える 1

1

設計上の問題

これを見た誰もが疑問に思うのは、なぜ計算列があるのか​​ということとFullName、次に、なぜこのプロパティがクライアントに公開されているのかということです。

計算された列には正当な理由があり、モデルが値自体を計算するのではなくテーブルから値を取得する正当な理由があり、クライアントに計算させるのではなくクライアントに送信する正当な理由があると仮定しましょう。 . 彼がそれについて私に言ったことは次のとおりです。

FullName「クエリに を含める必要があります」

人生は時々このようにうまくいきます。

結果

FullNameプロパティには public セッターがあることに注意してください。クラスの EF メタデータ ジェネレーターは、Personこれが読み取り専用プロパティであることを認識できません。FullNameのように見えますLastName。メタデータには、「これは通常の読み取り/書き込みプロパティです」と記載されています。

Breezeも違いはわかりません。クライアント アプリはこのプロパティに触れないかもしれませんが、Breeze は新しい を作成するときにその値を送信する必要がありますPerson。サーバーに戻ると、BreezeEFContextProviderは EF エンティティを作成するときにその値を渡す必要があると考えます。災害の舞台は整った。

(a) テーブルを変更できず、(b) モデルのFullNameプロパティ定義を変更できない場合、どうすればよいでしょうか?

解決策

EF はあなたの助けを必要としています。これが実際にはデータベースの計算されたプロパティであることを EF に伝える必要があります。EF 流暢なインターフェイスを使用するか、次に示すように属性を使用できます。

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public String FullName { get; 設定; }

この属性を追加すると、EF はこのプロパティが読み取り専用であることを認識します。Person適切なメタデータが生成され、新しいものをきれいに保存できます。それを省略すると、例外が発生します。

これは Code First でのみ必要であることに注意してください。モデル Database First を生成した場合、EF は列が計算されていることを認識し、列を設定しようとはしません。

ストアで生成されたキーに関する同様の問題に注意してください。整数キーのデフォルトは「ストア生成」ですが、Guid キーのデフォルトは「クライアント生成」です。テーブルで、データベースが実際に Guid を設定する場合は、ID[DatabaseGenerated(DatabaseGeneratedOption.Identity)] でプロパティをマークする必要があります。

于 2013-04-06T03:56:36.253 に答える