试图保存以逗号分隔的列表

时间:2013-03-03 14:48:30

标签: asp.net-mvc-3 nhibernate

尝试将选项从CheckBoxList保存为DB中的逗号分隔列表(string)(选择了一个或多个选项)。我正在使用代理以保存为string,否则我必须在数据库中为关系创建单独的表 - 对于这个简单的场景,这项工作不值得,我希望我可以将它转换为string并避免这种情况。

CheckBoxList使用enum作为选择:

public enum Selection 
{ 
    Selection1,
    Selection2,
    Selection3
}

不要错综复杂,但我使用[Display(Name="Choice 1")]和扩展类在UI上显示友好的内容。不确定我是否可以保存string而不仅仅是enum,但我认为如果我保存为enum,对我来说这对我来说并不是什么大问题。显示"在某些确认页面上的UI上的友好字符串。

这是"记录"在DB中保存string的类:

public virtual string MyCheckBox { get; set; }

这是&#34;代理&#34;,这是我找到但未直接处理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); 
    }
}

要保存在数据库中,我试图在创建类中执行此操作:

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

但是我收到了错误:

  

无法隐式转换&#39;字符串&#39; to System.Collections.Generic.IEnumerable&#39;

我不知道,如果可能或更好,可以使用API​​中的ParseToString作为枚举值。

我知道做这样的事情会将我放在("")中的任何内容存储到数据库中,所以它只是要弄清楚如何克服错误(或者,如果有的话)备选):

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

我对这些东西并不擅长,只是在挖掘和挖掘以提出解决方案。非常感谢任何帮助。

1 个答案:

答案 0 :(得分: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>();