0

CheckBoxList からの選択をカンマ区切りのリスト ( string) として DB に保存しようとしています (1 つ以上の選択肢が選択されています)。として保存するためにプロキシを使用していstringます。そうしないと、リレーション用にDBに個別のテーブルを作成する必要があるためです。この単純なシナリオでは、作業に価値がなく、単にstringそしてそれを避けてください。

CheckBoxList は、そのenum選択肢に を使用します。

public enum Selection 
{ 
    Selection1,
    Selection2,
    Selection3
}

複雑ではありませんが[Display(Name="Choice 1")]、拡張クラスを使用して、UI にわかりやすいものを表示します。stringの代わりにそれを保存できるかどうかはわかりませんが、確認ページのUIにわかりやすい文字列を「表示」することは大したことではないので、enum保存すると思います。enum

stringこれは、DB に保存する「レコード」クラスです。

public virtual string MyCheckBox { get; set; }

enumこれは「プロキシ」です。これは、私が見つけたサンプルですが、直接扱っていませIEnumerable<string>IEnumerable<Selection>

public IEnumerable<string> MyCheckBox
{
    get
    {
        if (String.IsNullOrWhiteSpace(Record.MyCheckBox)) return new string[] { };
            return Record
                .MyCheckBox
                .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(r => r.Trim())
                .Where(r => !String.IsNullOrEmpty(r));
    }
    set
    { 
        Record.MyCheckBox = value == null ? null : String.Join(",", value); 
    }
}

DBに保存するために、作成クラスでこれを実行しようとしています:

proxy.MyCheckBox = record.MyCheckBox; //getting error here

しかし、エラーが発生しています:

'string' を System.Collections.Generic.IEnumerable' に暗黙的に変換することはできません

列挙値に APIを使用するParseか、API から使用することが可能かどうかはわかりません。ToString

このようなことを行うと、入力したものはすべてDBに保存されることがわかっている("")ので、エラーを克服する方法を見つけるだけです(または、代替手段がある場合):

proxy.MyCheckBox = new[] {"foo", "bar"};

私はこのようなことが苦手で、解決策を考え出すために掘り下げていました。どんな助けでも大歓迎です。

4

1 に答える 1

0

これは、カスタム ユーザー タイプを使用して実現できます。以下の例ではISet<string>、クラスで を使用し、値を区切り文字列として格納します。

[Serializable]
public class CommaDelimitedSet : IUserType
{
    const string delimiter = ",";

    #region IUserType Members

    public new bool Equals(object x, object y)
    {
        if (ReferenceEquals(x, y))
        {
            return true;
        }
        var xSet = x as ISet<string>;
        var ySet = y as ISet<string>;
        if (xSet == null || ySet == null)
        {
            return false;
        }
        // compare set contents
        return xSet.Except(ySet).Count() == 0 && ySet.Except(xSet).Count() == 0;
    }

    public int GetHashCode(object x)
    {
        return x.GetHashCode();
    }

    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var outValue = NHibernateUtil.String.NullSafeGet(rs, names[0]) as string;
        if (string.IsNullOrEmpty(outValue))
        {
            return new HashSet<string>();
        }
        else
        {
            var splitArray = outValue.Split(new[] {Delimiter}, StringSplitOptions.RemoveEmptyEntries);
            return new HashSet<string>(splitArray);
        }
    }

    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        var inValue = value as ISet<string>;
        object setValue = inValue == null ? null : string.Join(Delimiter, inValue);
        NHibernateUtil.String.NullSafeSet(cmd, setValue, index);
    }

    public object DeepCopy(object value)
    {
        // return new ISet so that Equals can work
        // see http://www.mail-archive.com/nhusers@googlegroups.com/msg11054.html
        var set = value as ISet<string>;
        if (set == null)
        {
            return null;
        }
        return new HashSet<string>(set);
    }

    public object Replace(object original, object target, object owner)
    {
        return original;
    }

    public object Assemble(object cached, object owner)
    {
        return DeepCopy(cached);
    }

    public object Disassemble(object value)
    {
        return DeepCopy(value);
    }

    public SqlType[] SqlTypes
    {
        get { return new[] {new SqlType(DbType.String)}; }
    }

    public Type ReturnedType
    {
        get { return typeof(ISet<string>); }
    }

    public bool IsMutable
    {
        get { return false; }
    }

    #endregion
}

マッピング ファイルでの使用法:

Map(x => x.CheckboxValues.CustomType<CommaDelimitedSet>();
于 2013-03-05T16:22:35.313 に答える