2013-03-03 50 views
0

試圖從一個CheckBoxList的保存選擇如在DB以逗號分隔的列表(string)(選擇的一個或更多的選擇)。我使用的代理爲了保存爲string,否則我必須在數據庫中爲關係創建單獨的表格 - 這個工作對於這個簡單的場景並不值得,我希望我可以將它轉換爲一個string並避免這一點。試圖保存逗號分隔的列表

的CheckBoxList的使用它的選擇的enum

public enum Selection 
{ 
    Selection1, 
    Selection2, 
    Selection3 
} 

不被費解,但我用[Display(Name="Choice 1")]和擴展類來顯示的東西在UI友好。不知道如果我能救的那個string而不只是enum,但我想如果我保存爲enum它不是一個大不了我到「顯示」友好一些確認頁面上的UI字符串。

這是「記錄」類,它保存在一個數據庫中的string

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); 
    } 
} 

要保存在數據庫中,我試圖做到這一點在創建類:

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

,但我得到的錯誤:

Cannot implicitly convert 'string' to System.Collections.Generic.IEnumerable'

我不知道,如果可能的話或更好,使用ParseToString從枚舉值的API。

我知道,做這樣的事情將存儲無論我放在("")到數據庫,所以它只是一個搞清楚如何克服錯誤(或者,如果有另一種)的事情:

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

我對這個東西不太好,只是一直在挖掘和挖掘想出一個解決方案。任何幫助深表感謝。

+0

您的代碼對一個getter分裂 ''而二傳手加入','。那是對的嗎? – 2013-03-03 14:58:10

+0

對不起,這是一個錯字代碼 – 2013-03-03 15:00:38

+0

好的,所以你的代理的MyCheckBox是IEnumerable ,而Record.MyCheckBox是一個字符串。這兩個在分配時不兼容。我不確定我在這裏得到「代理」的目的。 – 2013-03-03 15:05:49

回答

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/[email protected]/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>();