Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 尝试根据Orchard中的枚举保存复选框选择(NHibernate)_Asp.net Mvc 3_Nhibernate_Orchardcms - Fatal编程技术网

Asp.net mvc 3 尝试根据Orchard中的枚举保存复选框选择(NHibernate)

Asp.net mvc 3 尝试根据Orchard中的枚举保存复选框选择(NHibernate),asp.net-mvc-3,nhibernate,orchardcms,Asp.net Mvc 3,Nhibernate,Orchardcms,我花了五(5)天的大部分时间试图找出如何使这项工作: 我使用enum,通过单选按钮列表、下拉列表(这些是多个选项中的一(1)个选项)以及复选框列表和多选列表(这些是多个选项中的一(1)对所有选项)存储用户输入的“选项” 现在,使用单选按钮列表和下拉列表,我在Orchard数据库中保存时没有问题。用户选择一个选项,该选项将作为所选的特定enum保存到数据库中 但是,使用复选框列表或多选择列表,我无法让Orchard/NHibernate保存多个选定的枚举 我已经尝试了所有我能在SO上或通过Goog

我花了五(5)天的大部分时间试图找出如何使这项工作:

我使用
enum
,通过单选按钮列表、下拉列表(这些是多个选项中的一(1)个选项)以及复选框列表和多选列表(这些是多个选项中的一(1)对所有选项)存储用户输入的“选项”

现在,使用单选按钮列表和下拉列表,我在Orchard数据库中保存时没有问题。用户选择一个选项,该选项将作为所选的特定
enum
保存到数据库中

但是,使用复选框列表或多选择列表,我无法让Orchard/NHibernate保存多个选定的
枚举

我已经尝试了所有我能在SO上或通过Google搜索找到的东西。唯一“可行”的解决方案是创建一个新表(通过迁移)/部分/部分记录组合,在某些情况下仅存储7-8个选项,这在这种情况下是过分的。然后,当然,我可以做一些类似于
公共虚拟IList{get;set;}
的事情

是的,我看过果园里的文件。有人认为,
LazyField
可能是一个解决方案。但看来(至少在我找到的信息或我看过的代码示例中,
LazyField
处理的是一个单独的表场景

请告诉我,我不需要一张单独的桌子来完成我想要完成的事情。再一次,这似乎是矫枉过正

下面是一个简单的例子,说明我正在尝试做什么:

public enum MyEnum
{
    Enum1,
    Enum2,
    Enum3,
    Enum4,
    Enum5
}
Selector.cs
有助于自动选择单选按钮、下拉列表、复选框或多选列表:

public class MySelectorAttribute : SelectorAttribute
{
    public override IEnumerable<SelectListItem> GetItems()
    {
        return Selector.GetItemsFromEnum<MyEnum>();
    }
}
Part.cs

[MyEnumSelector]
public virtual IList<string> MyEnumCheckBox { get; set; }
public IList<string> MyEnumCheckBox
{
    get { return Record.MyEnumCheckBox; }
    set { Record.MyEnumCheckBox = value; }
}
public IList MyEnumCheckBox
{
获取{return Record.MyEnumCheckBox;}
设置{Record.MyEnumCheckBox=value;}
}
注意:当我使用
时,我得到一个“表不存在”错误。如果改用
,则会出现强制转换错误(generic.list v.generic.icollection或某些变体)

我尝试了
IEnumerable
ICollection
这两种方法,但都有不同的错误消息

我不得不想象,Orchard/NHibernate会允许这种行为,而不需要我创建一个新的表来引用(在这种情况下,这似乎又是过分了)


如果有人能帮忙,我将不胜感激。我对这个问题束手无策。赏金?现金?你说吧。是的,我很绝望

您根本无法映射这样的列表。您需要与另一个记录/表建立适当的关系,或者可以使用逗号分隔的值列表等来管理存储。第一种情况当然有点干净,但是如果您不期望给定记录有太多的值,那么第二种情况就更容易了,而且坦率地说也很好


你可能还想考虑一个EnUM字段。

< p>你可以用<代码> [旗子] < /Cord>属性装饰你的<代码> Enm MyEnUng/<代码>,并将它的项的值设置为2的不同幂。例如,您的枚举可能如下所示:

[Flags]
public enum MyEnum
{
    Enum1 = 1,
    Enum2 = 2,
    Enum3 = 4,
    Enum4 = 8,
    Enum5 = 16
}
现在,
PartRecord
类的
MyEnumCheckBox
属性将是
int
类型:

public virtual int MyEnumCheckBox { get; set; }
您可以在
部分
类中创建代理属性。例如:

private IList<MyEnum> _myCheckBox;

[MyEnumSelector]
public IList<MyEnum> MyCheckBox
{
    get 
    {
        if (_myCheckBox == null)
        {
            _myCheckBox = new List<MyEnum>();

            foreach (MyEnum item in Enum.GetValues(typeof(MyEnum)))
            {
                if (((MyEnum)Record.MyEnumCheckBox & item) == item)
                    _myCheckBox.Add(item);
            }
        }

        return _myCheckBox;
    }
    set
    {
        _myCheckBox = value;
        Record.MyEnumCheckBox = 0;

        foreach (var item in value)
        {
           Record.MyEnumCheckBox |= (int)item;
        }
    }
}
private IList\u myCheckBox;
[髓鞘选择器]
公共IList MyCheckBox
{
得到
{
如果(_myCheckBox==null)
{
_myCheckBox=新列表();
foreach(Enum.GetValues中的MyEnum项(typeof(MyEnum)))
{
if(((MyEnum)Record.MyEnumCheckBox&item)=item)
_myCheckBox.Add(项目);
}
}
返回我的复选框;
}
设置
{
_myCheckBox=值;
Record.MyEnumCheckBox=0;
foreach(价值中的var项目)
{
Record.MyEnumCheckBox |=(int)项;
}
}
}
您可以找到有关Flags属性的更多信息。它基本上是为了使您能够对一个枚举字段使用多个枚举值,而这正是您要查找的内容


编辑:

我花了点时间构建了一个自定义模块来演示这项技术。我已经测试过了,它的工作方式应该是这样的。以下是消息来源:

迁移.cs

public int Create() 
{
  SchemaBuilder.CreateTable("MultipleEnumPickerRecord", table => table
    .ContentPartRecord()
    .Column<int>("SelectedItems"));

  ContentDefinitionManager.AlterPartDefinition("MultipleEnumPickerPart", p => p.Attachable());

  return 1;
}
public int Create()
{
CreateTable(“MultipleEnumPickerRecord”,table=>table
.ContentPartRecord()
。栏(“SelectedItems”);
ContentDefinitionManager.AlterPartDefinition(“MultipleEnumPickerPart”,p=>p.Attachable());
返回1;
}
型号:

[Flags]
public enum MyEnum
{
    Enum1 = 1, // bit-wise 00001 or 2^0
    Enum2 = 2, // bit-wise 00010 or 2^1
    Enum3 = 4, // bit-wise 00100 or 2^2
    Enum4 = 8, // bit-wise 01000 or 2^3
    Enum5 = 16 // bit-wise 10000 or 2^4
}

public class MultipleEnumPickerRecord : ContentPartRecord
{
    public virtual int SelectedItems { get; set; }
}

public class MultipleEnumPickerPart : ContentPart<MultipleEnumPickerRecord> 
{
    private IList<MyEnum> _selectedItems;

    public IList<MyEnum> SelectedItems
    {
        get
        {
            if (_selectedItems == null)
            {
                _selectedItems = new List<MyEnum>();

                foreach (MyEnum item in Enum.GetValues(typeof(MyEnum)))
                {
                    if (((MyEnum)Record.SelectedItems & item) == item)
                        _selectedItems.Add(item);
                }
            }

            return _selectedItems;
        }
        set
        {
            _selectedItems = value;
            Record.SelectedItems = 0;

            foreach (var item in value)
            {
                Record.SelectedItems |= (int)item;
            }
        }
    }
}
[标志]
公共枚举髓鞘
{
Enum1=1,//按位00001或2^0
Enum2=2,//按位00010或2^1
Enum3=4,//按位00100或2^2
Enum4=8,//按位01000或2^3
Enum5=16//按位10000或2^4
}
公共类MultipleNumpicKerreCord:ContentPartRecord
{
公共虚拟int SelectedItems{get;set;}
}
公共类MultipleEnumPickerPart:ContentPart
{
私人IList _selectedItems;
公共IList SelectedItems
{
得到
{
如果(_selectedItems==null)
{
_selectedItems=新列表();
foreach(Enum.GetValues中的MyEnum项(typeof(MyEnum)))
{
if(((MyEnum)Record.SelectedItems&item)=item)
_选择编辑项。添加(项);
}
}
返回_selectedItems;
}
设置
{
_selectedItems=值;
Record.SelectedItems=0;
foreach(价值中的var项目)
{
Record.SelectedItems |=(int)项;
}
}
}
}
处理程序:

public class MultipleEnumPickerHandler : ContentHandler
{
    public MultipleEnumPickerHandler(IRepository<MultipleEnumPickerRecord> repository)
    {
        Filters.Add(StorageFilter.For(repository));
    }
}
公共类multipleNumpickerHandler:ContentHandler
{
公共MultipleNumpickerHandler(IRepository存储库)
{
Filters.Add(StorageFilter.For(repository));
}
}
直接还原铁
public class MultipleEnumPickerDriver : ContentPartDriver<MultipleEnumPickerPart>
{

    protected override string Prefix { get { return "MultipleEnumPicker"; } }

    protected override DriverResult Editor(MultipleEnumPickerPart part, dynamic shapeHelper)
    {
        return ContentShape("Parts_MultipleEnumPicker_Edit", () => shapeHelper.EditorTemplate(
            TemplateName: "Parts/MultipleEnumPicker", Model: part, Prefix: Prefix));
    }

    protected override DriverResult Editor(MultipleEnumPickerPart part, IUpdateModel updater, 
        dynamic shapeHelper)
    {
        updater.TryUpdateModel(part, Prefix, null, null);
        return Editor(part, shapeHelper);
    }

}
<Placement>
    <Place Parts_MultipleEnumPicker_Edit="Content:5"/>
</Placement>
@using ModuleNamespace.Models
@model MultipleEnumPickerPart
<fieldset>
  <div class="editor-label">@Html.LabelFor(x => x.SelectedItems)</div>
  <div class="editor-field">
    <select multiple="multiple" id="@Html.FieldIdFor(x => x.SelectedItems)" name="@Html.FieldNameFor(x => x.SelectedItems)">
      @foreach (MyEnum item in Enum.GetValues(typeof(MyEnum))) {
        var selected = Model.SelectedItems.Contains(item);
        <option value="@((int)item)" @if(selected) {<text>selected="selected"</text>}>
          @T(item.ToString())
        </option>
      }
    </select>
  </div>
</fieldset>