gpt4 book ai didi

asp.net-mvc - 想要使用NHibernate将选定的(即多个)枚举保存为字符串

转载 作者:行者123 更新时间:2023-12-02 08:43:44 25 4
gpt4 key购买 nike

我一生都无法使用现有的代码,但是我正在尝试将enum选择保存为NHibernate中的字符串。基本上,我有一个UI复选框,如果用户选择了多个复选框,我想存储这些选择。现在,我可以让NHibernate存储一个选择(例如,从下拉列表或单选按钮列表中,其中用户仅限于一个选择)。
这是我列举的内容的精髓:

public enum IncomeType
{
[Display(Name = "Full-Time Employment")]
FullTime,
[Display(Name = "Part-Time Employment")]
PartTime,
[Display(Name = "Self-Employment")]
SelfEmployed,
[Display(Name = "Rental")]
Rental,
[Display(Name = "Social Security Payments")]
SocialSecurity,
[Display(Name = "Retirement / Pension Payments")]
Retirement,
[Display(Name = "Child Support Payments")]
ChildSupport,
[Display(Name = "Spousal Maintenance")]
Maintenance,
[Display(Name = "Other")]
Other
}
我使用一种方法来“选择”是否显示复选框列表(如果我的 BulkItemThreshold等于选项数,则会显示一个复选框列表)。这是该方法:
public static IEnumerable<SelectListItem> GetItemsFromEnumString<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)
};
}
(注意:其中有些项目有助手,但我不认为它们是相关的;而且,所选输入是使用模板 .cshtml文件显示的-再次不确定是否相关)
现在,我这样称呼它:
public class IncomeTypeSelectorAttribute : SelectorAttribute
{
public override IEnumerable<SelectListItem> GetItems()
{
return Selector.GetItemsFromEnumString<IncomeType>();
}
}
最后,我们进入 virtual属性(使用代理),但这是NHibernate扔扳手的地方(注意:在NHibernate之前,这对我来说很好用,现在我试图在不使用它的情况下获得许多代码行重新执行所有操作;如果重新执行所有操作,则可能会使我已经执行的代码增加三倍):
属性(记录):
[IncomeTypeSelector(BulkSelectionThreshold = 9)]
public virtual List<string> IndividualIncomeTypeCheckBox { get; set; }
代理(部分):
public List<string> IndividualIncomeTypeCheckBox
{
get { return Record.IndividualIncomeTypeCheckBox; }
set { Record.IndividualIncomeTypeCheckBox = value; }
}
同样,这是我的工作方式,在NHibernate之前运行良好。但是现在我必须使用NHibernate。没有绕过它。
我正在使用一个服务类,它将这两个类在Create方法中 bundle 在一起,以使用NHibernate保存在数据库中,对于上面的内容,它通常看起来像这样:
 part.IndividualIncomeTypeCheckBox = record.IndividualIncomeTypeCheckBox;
如果这只是一个选择,那将起作用。
好吧,我花了整整两(2)个月的时间来尝试使它生效。这很困难,因为我有很多代码,用户只能选择一个选项(例如带有单选按钮列表),并且可以很好地工作-即使使用NHibernate。让我举一个例子:
public virtual IncomeType? IndividualIncomeTypeCheckBox { get; set; }
如果执行上述操作,它将显示一个下拉列表,并且NHibernate将在数据库中存储用户选择的一个允许选项。但是 List<string>的多个选项不起作用。
现在,我尝试了在这里或其他地方可以找到的所有内容,但没有任何效果。是的,我知道它应该是 IList<IncomeType>或其他某种变体。但是,如果我使用这个,那么NHibernate要求 IncomeType是数据库中的另一个表。对于我认为如此简单的事情,这太多的代码无法编写。我们并不是在谈论多对多关系,因为这不是具有多个地址的用户(其中​​地址将具有街道,城市,州,邮政编码等)。
我尝试了不同类型的代理 getset代码,但没有任何效果。我已经尝试过 [Flags]和其他仅适用于 string的东西,但无济于事。这些最后的解决方案将“起作用”,但仅保存从多个中选择的第一个项目(即,在我的方案中,如果用户选择“FullTime”和“Rental”作为收入类型,则只有“FullTime”( string)是已保存或为“1”( [Flags] / int),但未同时选择两项。
我遇到这样的情况,我使用 ReadOnly属性重新显示选择,如下所示:
[IncomeTypeSelector]
[ReadOnly(true)]
public List<string> IndividualIncomeTypeCheckBoxPost
{
get { return IndividualIncomeTypeCheckBox; }
}
这将显示在UI上,但是我尝试使用NHibernate做类似的事情,但是它不起作用。
任何人都可以使用上述内容,向我展示如何使NHibernate在此复选框列表方案中存储多个 enum吗?
更新:
在这里和在网络上玩的更多,我想到了以下内容(仍然无法使用)。
属性(记录):
[IncomeTypeSelector(BulkSelectionThreshold = 9)]
public virtual IList<IncomeTypeRecord> IndividualIncomeTypeCheckBox
{
get { return incomeType; }
set { incomeType= value; }
}
private IList<IncomeTypeRecord> incomeType =
new List<IncomeTypeRecord>();
代理(部分):
public IList<IncomeTypeRecord> IndividualIncomeTypeCheckBox
{
get { return Record.IndividualIncomeTypeCheckBox; }
set { Record.IndividualIncomeTypeCheckBox= value; }
}
并更改枚举:
public enum IncomeType : int // removing int & value still gives validate error
{
[Display(Name = "Full-Time Employment")]
FullTime = 1,
[Display(Name = "Part-Time Employment")]
PartTime,
....
}
我添加了此类以支持 IncomeTypeRecord
public class IncomeTypeRecord
{
public virtual int Id { get; set; }
public virtual IncomeType Value { get; set; }
}
但是,当我进入UI屏幕并选择一个或多个选项时,会收到验证错误(值无效)。例如,假设我单独选择FullTime,或选择FullTime和Retirement,则UI将显示以下错误:

The value 'FullTime' is invalid.

The value 'FullTime,Retirement' is invalid.


(分别)
即使删除了 intenum声明并摆脱了以“1”开头的值,我仍然会收到此验证错误。我尝试弄乱并添加了不同的模型联编程序(现在让我感到困惑的是,我原来的问题是否仍然存在,而现在我又遇到了另一个问题-但您仍然会得到赏金:))。
拉我的头发。如果我可以提供更多的赏金,我会的。我需要一个确定的解决方案。感谢您的帮助。
更新
这是我到目前为止所拥有的:
记录:
public virtual string IndividualIncomeTypeCheckBox{ get; set; }
部分:
//If I do IEnumberable<string> my .Select throws a cast error
public IEnumerable<IncomeType> IndividualIncomeTypeCheckBox
{
get
{
return Record
.IndividualIncomeTypeCheckBox
.Split(',')
.Select(r => (IncomeType)Enum.Parse(typeof(IncomeType), r));
}
set { Record.IndividualIncomeTypeCheckBox= value
== null ? null : String.Join(",", value); }
}
服务等级:
public SimplePart CreateSimple(SimplePartRecord record)
{
SimplePart simple = Services.ContentManager.Create<SimplePart>("Simple");
...
//How I would save a FirstName property (example Part / PartRecord below)
//public virtual string FirstName { get; set; } - PartRecord
//public string FirstName - Part
//{
// get { return Record.FirstName ; }
// set { Record.FirstName= value; }
//}
simple.FirstName = record.FristName;
...
//I obviously cannot do the following with the above IncomeType
//Getting cannot convert string to IEnumerable error
//How would I write this:
simple.IndividualIncomeTypeCheckBox = record.IndividualIncomeTypeCheckBox;
...
}
这就是它在 Controller 中的调用方式(这一直存在于数据库中): (更新 Controller 代码)
public ActionResult Confirm(string backButton, string nextButton)
{
if (backButton != null)
return RedirectToAction("WrapUp");
else if ((nextButton != null) && ModelState.IsValid)
{
_myService.CreateSimple(myData.SimplePartRecord);
return RedirectToAction("Submitted");
}
else
return View(myData);
}
使用其他代码(序列化和 View 模型)更新:
在 Controller 中(使用序列化)将“myData”定义为:
private MyViewModel myData;
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var serialized = Request.Form["myData"];
if (serialized != null)
{
myData = (MyViewModel)new MvcSerializer().Deserialize
(serialized, SerializationMode.Signed);
TryUpdateModel(myData);
}
else
myData = (MyViewModel)TempData["myData"] ?? new MyViewModel();
TempData.Keep();
}
protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
if (filterContext.Result is RedirectToRouteResult)
TempData["myData"] = myData;
}
我使用序列化是因为我在前端设置了一个多步骤向导(如 Controller 操作“backButton”和“nextButton”所示),我没有使用驱动程序(只能显示Admin或在前端显示,但可以则仅在直接位于〜/ Views文件夹下的.cshtml文件上(而不是在我正在使用的结构化文件夹列表中)。没有驱动程序=没有更新 View 模型类型代码=没有在数据库中“创建”数据的机制。我不使用某些“创建”类型的方法,该表单将提交,但所有数据将为“NULL”。
当您说应该自动保留数据时,很抱歉,但我看不到如何。我阅读或审查的所有代码都有一些使用表格中输入内容更新数据库的方法。如果我缺少什么,我深表歉意。
“MyViewModel”非常简单:
[Serializabel]
public class MyViewModel
{
public SimplePartRecord SimplePartRecord { get; set; }
}
并且,以防万一,这是迁移的相关部分(返回1是完全独立且不相关的表):
public int UpdateFrom1()
{
SchemaBuilder.CreateTable("SimplePartRecord",
table => table
.ContentPartRecord()
...
.Column("IndividualIncomeTypeCheckBox", DbType.String)
...
);
ContentDefinitionManager.AlterPartDefinition("SimplePart",
part => part
.Attachable(false));
return 2;
}
我得到的错误是

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


当我在服务类的“创建”方法中执行以下操作时:
simple.IndividualIncomeTypeCheckBox = record.IndividualIncomeTypeCheckBox;
另外一个想法:我尝试使用n-n Relation示例处理这种情况。除了它之外,还有很多我认为应该简单明了的代码,由于我使用序列化的方式,我遇到了很多对象引用错误,并且无法弄清楚如何正确编码我的 Controller 来处理它。

最佳答案

问题是,如果不与中间关联表建立完整的关系,就无法映射List。使用记录将值存储为逗号分隔的字符串(因此您的record属性是一个字符串,而不是字符串列表)更加简单,并且您的部分可以在string和List之间来回映射。

您可以在此处找到非常接近的示例:

https://bitbucket.org/bleroy/nwazet.commerce/src/d722cbebea525203b22c445905c9f28d2af7db46/Models/ProductAttributesPartRecord.cs?at=default

https://bitbucket.org/bleroy/nwazet.commerce/src/d722cbebea525203b22c445905c9f28d2af7db46/Models/ProductAttributesPart.cs?at=default

它没有使用枚举值,而是一个ID列表,但这应该使您对如何使此工作相当简单有一个好主意:解析枚举您已经知道该怎么做。

让我知道您是否需要更多详细信息,但是我认为这是您畅通无阻的方法。

关于asp.net-mvc - 想要使用NHibernate将选定的(即多个)枚举保存为字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14288249/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com