我正在使用enum
's 和一个自定义Selector
类来帮助在单选按钮、下拉菜单、复选框等之间进行选择。我正在使用 NHibernate。通过单个选择(单选按钮、下拉菜单),来自属性的值[Display(Name = "[Some Text]")]
将填充到数据库表中(注意:我使用的是扩展名Display(Name)
)。但是,对于多个选择(复选框、多列表),我无法弄清楚如何将enum
选择的值输入数据库。
这是我的模型的一部分(每个都在单独的文件中)(编辑:我给了它们通用名称,以免进一步混淆问题):
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<SelectListItem> GetItems()
{
return Selector.GetItemsFromEnum<MyEnum>();
}
}
...
[Display(Name = "This is a checkboxlist (select one or more check boxes)?")]
[MyEnumSelector(BulkSelectionThreshold = 10)]
public virtual List<string> MyEnumCheckBox { get; set; }
...
public List<string> MyEnumCheckBox
{
get { return Record.MyEnumCheckBox; }
set { Record.MyEnumCheckBox = value; }
}
这是Selector.cs
帮助选择单选按钮、复选框、下拉菜单等的类(如果它与问题相关):
public class Selector
{
public IEnumerable<SelectListItem> 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<DisplayAttribute>()
.FirstOrDefault();
if (display != null)
{
return display.Name;
}
return value;
}
public static IEnumerable<SelectListItem> GetItemsFromEnum<T>
(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<SelectListItem> ToSelectList
(this IEnumerable data)
{
return new SelectList(data);
}
public static IEnumerable<SelectListItem> ToSelectList
(this IEnumerable data, string dataValueField,
string dataTextField)
{
return new SelectList(data, dataValueField, dataTextField);
}
public static IEnumerable<SelectListItem> ToSelectList<T>
(this IEnumerable<T> data, Expression<Func<T, object>>
dataValueFieldSelector, Expression<Func<T, string>>
dataTextFieldSelector)
{
var dataValueField = dataValueFieldSelector.ToPropertyInfo().Name;
var dataTextField = dataTextFieldSelector.ToPropertyInfo().Name;
return ToSelectList(data, dataValueField, dataTextField);
}
}
该类Selector
与一个模板配对,该模板Selector.cshtml
具有一些逻辑来确定选择哪个(单选按钮、复选框等)。
我在尝试List<string>
、List<MyEnum>
、IList<string>
、IList<MyEnum>
和IEnumerable<MyEnum>
时遇到各种错误IEnumerable<MyEnum>
。此错误仅与复选框或多列表一起出现,因为它们使用List<string>
. 例如,下拉菜单可以正常工作,没有错误。这是一个示例下拉模型(可以enum
在上面重复使用),它可以通过 NHibernate 映射到数据库:
[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; }
}
根据我的尝试,以下是我遇到的一些错误:
List<string>
错误:
NHibernate.Transaction.ITransactionFactory - DTC 事务准备阶段失败 NHibernate.PropertyAccessException: Invalid Cast (检查你的映射是否有属性类型不匹配); MyNameSpace.Models.MyRecord 的 setter ---> System.InvalidCastException:无法转换类型为“NHibernate.Collection.Generic.PersistentGenericBag
1[System.String]' to type 'System.Collections.Generic.List
1[System.String]”的对象。
List<MyEnum>
错误:
NHibernate.Transaction.ITransactionFactory - DTC 事务预处理阶段失败 System.InvalidCastException:无法转换类型为“System.Collections.Generic.List
1[MyNameSpace.Models.MyEnum]' to type 'System.Collections.Generic.ICollection
1 [System.String]”的对象。
IList<string>
错误:
NHibernate.AdoNet.AbstractBatcher - 无法执行命令:INSERT INTO MyEnumCheckBox (MyRecord_id, Value) VALUES (@p0, @p1) System.Data.SqlServerCe.SqlCeException (0x80004005):指定的表不存在。[我的枚举检查框]
我尝试的其他变体是类似的错误,除了如果我使用<MyEnum>
它会显示如下错误:
System.Collections.Generic.List
1[MyNameSpace.Models.MyEnum]' to type 'System.Collections.Generic.ICollection
1 [System.String]'。
enum
在尝试enum
使用 NHibernate 插入多个选定的 s时,关于如何在这种情况下使用 's 的任何想法?