2012-07-02 22 views
8

コードファーストクラス/テーブルがあり、フィールドの1つにstring/nvarchar型があります。この文字列は、MyClassインスタンスのJSON表現です。私はMyClassインスタンスでのみコードを操作したいが、それをデータベースに文字列(JSON)として保存したい。のは、私のテーブルは次のようになりましょう:エンティティフレームワーク:シーンの背後にあるJSON列のシリアル化/逆シリアル化

public class Message 
{ 
    [Key] 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public string JsonDefinition { get; set; } 
} 

私はJSONは、MyClassのインスタンスのフィールドとしてシリアライズされた文字列を格納するEFを伝えカスタム属性であるこの

public class Message 
{ 
    [Key] 
    public int Id { get; set; } 
    public string Title { get; set; } 
    [JSON] 
    public MyClass JsonDefinition { get; set; } 
} 

ようにそれを持っていることを好むだろう。同時に、EFは次のように述べています。「いったんエンティティを取得すると、JsonDefinition文字列をMyClassの逆シリアル化されたインスタンスに置き換えてください。」

既存のEF 4メカニズムでは実現できますか?もしそうなら、どのように?

ありがとうございます。

EDIT:MyClassは、ディクショナリまたはその他の複合型です。

+0

tisが役立つかもしれません:http://www.reddnet.net/entity-framework-json-column/ –

答えて

8

直接ではありません。永続性のためにEFが要求するので、クラスには常に文字列プロパティが存在する必要があります。また、マップされていないMyClassプロパティを持つこともできますが、シリアライズとデシリアライズを手動で処理して、それらのプロパティを同期させる必要があります。

あなたのMyClassにINotifyPropertyChangedを実装し、MyClass値またはそのプロパティのすべての変更がJSONのシリアル化を文字列プロパティにトリガーするようにすることです。この素朴なソリューションはいくつかの単純な問題にも役立ちますが、割り当てられたMyClassプロパティで多くのプロパティを変更すると、パフォーマンスに大きな影響を与える可能性があるため、この場合は本当に悪い考えです。

もう1つの方法は、EFのフックを使用してマテリアライゼーションと変更を保存することです。 ObjectContext.ObjectMaterializedイベントを処理する必要があります(DbContextによって明示的に実装されたIObjectContextAdapterを介してDbContextからObjectContextを得ることができます)。このイベントハンドラでは、文字列プロパティの値を使用して内容をMyClassプロパティに逆シリアル化します。また、Messageインスタンスをすべて挿入したり更新したりして、MyClassプロパティを使用して現在の値を取得し、それを文字列プロパティにシリアル化する場合は、DbContext.SaveChangesをオーバーライドする必要があります。

あなたが探しているのは、複雑なマッピングシナリオやマップされたコンバージョンです。 EFはそれらをサポートしていませんが、Data UserVoiceに関する私の提案に投票することができます。

+0

エンティティのフックを使用するのではなく、プロパティgetterがオンデマンドでシリアル化を行うようにすることができます。セッターはデシリアライズを行いますオブジェクトの残りの部分を移入しますか? –

+0

@KevinKiblerこれはINotifyPropertyChangedソリューションと同じ問題がありますが、うまくいくでしょう。 – Casey