AzureテーブルストレージエミュレーションでEFとAutoMapperを使用しています。
Fragment(シリアライズ可能なDTO)とFragmentEntity(EF永続化DO)の2つのタイプがあります。AutoMapperを使用してDTOからDOにマップし、PUT呼び出しで永続化し、GET呼び出しでその逆を行います。
問題は、EFとAutoMapperの両方に関する私の経験不足です。FragmentEntityクラスを(見つけたドキュメントに従って)データベースでフラグメントのIDを生成するように構成しました(以下を参照)。
エンティティIDの定義:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int? Id { get; set; }
実行時に、httpクライアントは新しいコンテンツ(フラグメント)を使用してRESTPUT呼び出しを行います。これはWCFを介して受信され、次のようにフラグメントにシリアル化されます。
[OperationContract]
[WebInvoke(UriTemplate = "/Fragments", Method = "PUT")]
void PutFagment(Fragment fragment);
デバッグ中にコードをステップオーバーすると、受信したID値はnullになります(IDプロパティをオプションとして定義したため)。
public void PutFagment(Fragment fragment)
{
var fragmentEntity = Mapper.Map<Fragment, FragmentEntity>(fragment);
_fragmentContext.Add(fragmentEntity);
}
[DataMember]
public virtual int? Id { get; set; }
それをオプションとして定義することが賢明な動きであったかどうかはわかりません。これを行ったのは、オプションでない場合、値のデフォルトがゼロになり、オートマッパーがターゲットのFragmentEntityにマップし、その後、データベース内のすべてのキーがゼロ(明らかに間違っている)になるためです。
アプリケーションコードに値を設定しないようにFragmentEntityIdもオプションにしたので、nullの場合はデータベースの生成が発生する可能性がありますが、発生していないように見えます。
<Fragment><Id i:nil="true"/><Name>Drei</Name><Type>3</Type></Fragment>
私の問題:
- 両方のクラスでIdをオプションにするという決定は正しくないと思います。このケースを適切に処理するAutoMapper構成がいくつかあり、両方を非オプションのままにしておくことができると思います。
- DatabaseGenerated属性が有効にならない理由がわかりません。