title: NHibernate: Enum to list and store values in database
body: <p>I am using <code>enum</code>'s and a custom <code>Selector</code> class to help choose between radiobuttons, dropdowns, checkboxes, etc. I am using NHibernate. With a single selection (radiobuttons, dropdowns), the value from attribute <code>[Display(Name = "[Some Text]")]</code> will be populated in the database table (NOTE: I am using an extension to use <code>Display(Name)</code>). However, with multiple selections (checkboxes, multilist), I cannot figure out how to get the values of the <code>enum</code> selections into the database.</p>
  
  <p>Here are parts of my model (each in separate files) (EDIT: I gave them generic names so as not to further confuse the issue):</p>
  
  <pre><code>public enum MyEnum
  {
      [Display(Name = "Text for enum1")]
      enum1,
      //Left out 2 - 10 for brevity
      [Display(Name = "Text for enum10")]
      enum10
  }
  ...
  public class MyEnumSelectorAttribute : SelectorAttribute
  {
      public override IEnumerable&lt;SelectListItem&gt; GetItems()
      {
          return Selector.GetItemsFromEnum&lt;MyEnum&gt;();
      }
  }
  ...
  [Display(Name = "This is a checkboxlist (select one or more check boxes)?")]
  [MyEnumSelector(BulkSelectionThreshold = 10)]
  public virtual List&lt;string&gt; MyEnumCheckBox { get; set; }
  ...
  public List&lt;string&gt; MyEnumCheckBox
  {
      get { return Record.MyEnumCheckBox; }
      set { Record.MyEnumCheckBox = value; }
  }
  </code></pre>
  
  <p>And here is the <code>Selector.cs</code> class (in case it's relevant to the problem) that help's to choose radiobuttons, checkboxes, dropdowns, etc.:</p>
  
  <pre><code>public class Selector
  {
      public IEnumerable&lt;SelectListItem&gt; Items { get; set; }
  
      public string OptionLabel { get; set; }
  
      public bool AllowMultipleSelection { get; set; }
  
      public int BulkSelectionThreshold { get; set; }
  
      public static string GetEnumDescription(string value, Type enumType)
      {
          var fi = enumType.GetField(value.ToString());
          var display = fi
              .GetCustomAttributes(typeof(DisplayAttribute), false)
              .OfType&lt;DisplayAttribute&gt;()
              .FirstOrDefault();
          if (display != null)
          {
              return display.Name;
          }
          return value;
      }
  
      public static IEnumerable&lt;SelectListItem&gt; GetItemsFromEnum&lt;T&gt;
          (T selectedValue = default(T)) where T : struct
      {
          return from name in Enum.GetNames(typeof(T))
                 let enumValue = Convert.ToString((T)Enum.Parse
                     (typeof(T), name, true))
  
                 select new SelectListItem
                 {
                     Text = GetEnumDescription(name, typeof(T)),
                     Value = enumValue,
                     Selected = enumValue.Equals(selectedValue)
                 };
      }
  }
  
  public static class SelectorHelper
  {
      public static IEnumerable&lt;SelectListItem&gt; ToSelectList
          (this IEnumerable data)
      {
          return new SelectList(data);
      }
  
      public static IEnumerable&lt;SelectListItem&gt; ToSelectList
          (this IEnumerable data, string dataValueField, 
          string dataTextField)
      {
          return new SelectList(data, dataValueField, dataTextField);
      }
  
      public static IEnumerable&lt;SelectListItem&gt; ToSelectList&lt;T&gt;
          (this IEnumerable&lt;T&gt; data, Expression&lt;Func&lt;T, object&gt;&gt; 
          dataValueFieldSelector, Expression&lt;Func&lt;T, string&gt;&gt; 
          dataTextFieldSelector)
      {
          var dataValueField = dataValueFieldSelector.ToPropertyInfo().Name;
          var dataTextField = dataTextFieldSelector.ToPropertyInfo().Name;
          return ToSelectList(data, dataValueField, dataTextField);
      }
  }
  </code></pre>
  
  <p>The <code>Selector</code> class is paired with a template <code>Selector.cshtml</code> that has some logic to figure out which to pick (radiobutton, checkboxes, etc.). </p>
  
  <p>I am getting various errors trying either <code>List&lt;string&gt;</code>, <code>List&lt;MyEnum&gt;</code>, <code>IList&lt;string&gt;</code>, <code>IList&lt;MyEnum&gt;</code>, <code>IEnumerable&lt;MyEnum&gt;</code> and <code>IEnumerable&lt;MyEnum&gt;</code>. This error only comes with checkboxes or multilists since they use <code>List&lt;string&gt;</code>. Dropdowns, for example, work fine with no errors. Here is a sample dropdown model (can reuse <code>enum</code> above) that works and will allow mapping to the DB through NHibernate:</p>
  
  <pre><code>[Required(ErrorMessage = "Please select one option")]
  [Display(Name = "This is a dropdown list (select one option)?")]
  [MyEnumSelector(BulkSelectionThreshold = 0)] //0 selects dropdown
  public virtual MyEnum? MyEnumDropDown { get; set; }
  
  public MyEnum? MyEnumDropDown
      {
          get { return Record.MyEnumDropDown; }
          set { Record.MyEnumDropDown = value; }
      }
  </code></pre>
  
  <p>Here are some of the errors I am getting based on what I've tried:</p>
  
  <p><strong><code>List&lt;string&gt;</code> error:</strong></p>
  
  <blockquote>
    <p>NHibernate.Transaction.ITransactionFactory - DTC transaction prepre phase failed
    NHibernate.PropertyAccessException: Invalid Cast (check your mapping for property type mismatches); setter of MyNameSpace.Models.MyRecord ---> System.InvalidCastException: Unable to cast object of type 'NHibernate.Collection.Generic.PersistentGenericBag<code>1[System.String]' to type 'System.Collections.Generic.List</code>1[System.String]'.</p>
  </blockquote>
  
  <p><strong><code>List&lt;MyEnum&gt;</code> error:</strong></p>
  
  <blockquote>
    <p>NHibernate.Transaction.ITransactionFactory - DTC transaction prepre phase failed
    System.InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List<code>1[MyNameSpace.Models.MyEnum]' to type 'System.Collections.Generic.ICollection</code>1[System.String]'.</p>
  </blockquote>
  
  <p><strong><code>IList&lt;string&gt;</code> error:</strong></p>
  
  <blockquote>
    <p>NHibernate.AdoNet.AbstractBatcher - Could not execute command: INSERT INTO MyEnumCheckBox (MyRecord_id, Value) VALUES (@p0, @p1)
    System.Data.SqlServerCe.SqlCeException (0x80004005): The specified table does not exist. [ MyEnumCheckBox ]</p>
  </blockquote>
  
  <p>The other variations I tried were similar errors, except that if I used <code>&lt;MyEnum&gt;</code> it would show an error like this:</p>
  
  <blockquote>
    <p>System.Collections.Generic.List<code>1[MyNameSpace.Models.MyEnum]' to type 'System.Collections.Generic.ICollection</code>1[System.String]'.</p>
  </blockquote>
  
  <p>Any thoughts on how to use <code>enum</code>'s in this scenario when trying to insert multiple selected <code>enum</code>s using NHibernate?</p>