8

私はCodeFirstクラス/テーブルを持っており、フィールドの1つはstring/nvarchar型を持っています。この文字列は、MyClassインスタンスのJSON表現です。MyClassインスタンスのみを使用してコードで操作したいのですが、データベースに文字列(JSON)として保存します。私のテーブルが次のようになっているとしましょう。

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

こんな感じにしたい

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

ここで、JSONは、フィールドをMyClassインスタンスのシリアル化された文字列として格納するようにEFに指示するカスタム属性です。同時に、EFと表示されます。「エンティティをプルしたら、JsonDefinition文字列をMyClassの逆シリアル化されたインスタンスに置き換えます」

既存のEF4メカニズムで達成することは可能ですか?もしそうなら、どのように?

前もって感謝します。

編集:MyClassは、辞書またはその他の複合型にすることができます。

4

2 に答える 2

8

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

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

もう1つの方法は、EFのフックを使用して、変更を具体化および保存することです。イベントを処理する必要があります(によって明示的に実装された経由でObjectContext.ObjectMaterialized取得できます)。このイベントハンドラーでは、文字列プロパティの値を使用し、そのコンテンツをプロパティに逆シリアル化します。また、挿入または更新する必要があるすべてのインスタンスを探す場所をオーバーライドし、それらのプロパティを使用して現在の値を取得し、文字列プロパティにシリアル化する必要があります。ObjectContextDbContextIObjectContextAdapterDbContextMyClassDbContext.SaveChangesMessageMyClass

あなたが探しているのは、いくつかの複雑なマッピングシナリオまたはマップされた変換です。EFはそれらをサポートしていませんが、DataUserVoiceに関する私の提案に投票することができます

于 2012-07-03T08:23:28.453 に答える
2

私は次のように何かを試みます:

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

    [Column(TypeName = "jsonb")]
    [JsonIgnore]
    public string JMyClass { get; set; }

    [NotMapped]
    public MyClass JsonDefinition 
    {
        get => JsonConvert.DeserializeObject<MyClass>(JMyClass );
        set => JMyClass = JsonConvert.SerializeObject(value);
    }
}
于 2019-03-25T14:13:38.340 に答える