web-dev-qa-db-ja.com

Entity Framework Code First List <string>プロパティマッピング

私は最初にEntityFrameworkCodeを使用しています。私は単純なモデルを持っています:

public class Variable
{
    public string Name { get; set; }

    public int Id { get; set; }

    public IList<string> TextOptions
    {
        get;
        set;
    }
}

プロパティTextOptionsのタイプがList<String>であるという問題が発生しました。

Entity Frameworkでこれを実行しようとすると、マップされません。

私はここで私の問題を修正する解決策(stackoverflow)を見つけました。私は基本的にクラスを作り直して、リストを取得し、代わりに永続化される区切り文字列にします。

public class Variable : IVariable
{
    public string Name { get; set; }

    public int Id { get; set; }

    public virtual IList<string> TextOptions
    {
        get
        {

            return _TextOptions;

        }
        set
        {
            _TextOptions = value;
        }
    }

    private IList<string> _TextOptions;

    public string TextOptionsSerialized
    {
        get
        {
            return String.Join(";", _TextOptions);
        }
        set
        {
            _TextOptions = value.Split(new char[]{';'}, StringSplitOptions.RemoveEmptyEntries).ToList();
        }
    }
}

このコードは正常に機能します。私が抱えている問題は、それが関心の分離に違反していると思うことです。私のモデルクラスは、Entity Frameworkがそれを永続化できるように、文字列のリストをシリアル化することに関係するべきではないと思います。

ASP.NetMVCで動作している同様の問題に遭遇しました。モデルにマッピングされる投稿がクライアントから送信されました。投稿と比較して、モデルの構造にいくつかの問題がありました。 MVCでは、非常に安全で再利用可能な方法で変換を処理するカスタムモデルバインダーを作成できました。

カスタムモデルバインダーがMVC用であるのと同じくらいクリーンなEntityFrameworkに対してこれを行う方法はありますか?

23
Mike Bynum

いいえ、EFには、MVCのモデルバインダーの代わりとなるタイプコンバーターやカスタムタイプマッパーはありません。永続性を強制するには、常に何らかのハックを使用する必要があります。同じことを行う別の方法は、関連するエンティティのコレクションとしてTextOptionsをマッピングすることです。関心の分離は改善されますが、モデルとVariableの操作が複雑になります。

public class Variable
{
    public string Name { get; set; }

    public int Id { get; set; }

    public IList<TextOption> TextOptions
    {
        get;
        set;
    }
}

public class TextOption
{
    public int Id { get; set; }
    public string Text { get; set; }
}
26
Ladislav Mrnka

3番目のオプションは、JSON.NETを使用してシリアル化を行うことです。

このスレッドにリストされている3つのオプション(文字列分割シリアル化、JSON.NET、エンティティの導入)を使用して、書き込みシナリオのパフォーマンステストをいくつか実行したところ、JSON.NETが最高のパフォーマンスを発揮することがわかりました。

200個の等しいエンティティの予備的な書き込み結果( ここのソースコードを参照して、自分でテストを実行してください ):

  • 文字列シリアライザーを使用してエンティティを書き込む時間:896ミリ秒
  • Jsonシリアライザーを使用してエンティティを書き込む時間:516ミリ秒
  • 複数のエンティティを使用してエンティティを書き込む時間:706ミリ秒

JSONシリアライザーを使用したサンプル:

public class VariableJson
{
    public string Name { get; set; }

    public int Id { get; set; }

    public virtual IList<string> TextOptions
    {
        get
        {

            return _TextOptions;

        }
        set
        {
            _TextOptions = value;
        }
    }

    private IList<string> _TextOptions;

    public string TextOptionsSerialized
    {
        get
        {
            return JsonConvert.SerializeObject(_TextOptions);
        }
        set
        {
            _TextOptions = JsonConvert.DeserializeObject<IList<string>>(value);                    
        }
    }
}
7
Mauricio Aviles