gpt4 book ai didi

c# - 设计指南 - 来自数据库中松散类型键/值的动态 ViewModel

转载 作者:太空宇宙 更新时间:2023-11-03 13:30:15 25 4
gpt4 key购买 nike

我有一个让我头疼的场景,我认为我的方向是正确的,现在我发现了另一个问题。这很复杂,让我们从数据库开始:

我有一个表,其中包含一个键、一个值、一个 typeId 和一些其他属性。我所关心的只是键和值。我的 View 模型包含我从 nhibernate 在存储库层中使用的数据对象映射的域对象的列表。在这里:

public class DomainModel
{
public string Key { get; set; }
public string Value { get; set; }
public TypeEnum Type { get; set; }
}

**注意,TypeEnum 与 Key 的 Value 的强类型无关。这只是对键/值进行分类的一种不同方式,以便我可以按该类型从数据库中提取它们。

简单。这是我的 View 模型:

public class ViewModel
{
public List<DomainModel> Models { get; set; }
}

我遇到的问题是键的值是不同的数据类型。有时它们是 bool 值,我想要一个 Html.CheckBoxFor(model => model.Value),有时它们是字符串,一个 Html.TextBoxFor(model => model.Value) 就足够了。

这是我的 Razor View :

@foreach (var setting in Model.Models)
{
<tr>
<td>@Html.Label(setting.Key)</td>
<td>@Html.TextBox(setting.Value)</td>
</tr>
}

在此处切分应用程序的最佳区域是什么,并进行一些类型检查或其他操作,以便我在页面上具有适当的 Html 元素?我什至会怎么做呢?我在这里错过了一些非常明显和简单的东西吗?此外,如何根据键的值获取键的显示名称属性?它们目前只是 PacalCasedBunchedDescriptionNames。我是不是离设计太远了还是怎么的?

最佳答案

我最终所做的只是让 View 和 View 模型保持平坦,而不是尝试在那里进行一些动态类型暗示。这也让我能够保持我的验证和其他属性整洁。

域模型仍然是一样的,我实际上最终删除了类型,并在我的业务层中创建了一个 SaveDomainModel,因为每次我保存/更新一个集合时,它只针对一种类型的设置:

public class SaveDomainModel
{
public List<DomainModel> DomainModels { get; set; }
public SettingTypeEnum SettingType { get; set; }
}

我将我的 DomainModel 更改为:

public class DomainModel
{
[Required]
public string Key { get; set; }
[Required]
public string Value { get; set; }
}

并展平我的 ViewModel:

public class EditViewModel
{
[DisplayName("Display Name:")]
[Required]
public int AnIntProp { get; set; }

[DisplayName("Another Display Name:")]
[Required]
public string HereIsAString { get; set; }

[DisplayName("Bool Display:")]
[Required]
public bool ImABool{ get; set; }
}

所以现在我的 Controller 对于 POST 看起来像这样:

[HttpPost]
public virtual ActionResult Edit(EditViewModel viewModel)
{
if (ModelState.IsValid)
{
SaveSettings(viewModel);
return RedirectToAction(MVC.Settings.Edit());
}
return View(viewModel);
}

private void SaveSettings(EditViewModel viewModel)
{
var settings = MapEditViewModelToDomainModels(viewModel);
var saveDomainModel = new SaveDomainModel
{
DomainModels = settings,
SettingType = SettingTypeEnum.Application
};
_settingsService.SaveSettings(saveDomainModel);
}

这确实是我之前没有发现的缺失链接,我在这篇文章中偶然发现了它:Enumerating through an object's properties (string) in C#

然后为了从平面 View 模型映射到域对象,我在 SaveSettings() 中使用了 Map... 函数。

private static List<DomainModel> MapEditViewModelToDomainModels(EditViewModel viewModel)
{
var settings = new List<DomainModel>();

var stringPropertyNamesAndValues = viewModel.GetType().GetProperties().Where(p => p.CanRead).Select(p => new {Name = p.Name, Value = p.GetValue(viewModel, null)});
foreach (var pair in stringPropertyNamesAndValues)
{
var model= new DomainModel
{
Key = pair.Name,
Value = pair.Value.ToString()
};
settings.Add(model);
}

return settings;
}

然后我就可以像这样保持我的视野平坦:

<tr>
<td>@Html.LabelFor(model => model.SomeString)</td>
<td>@Html.TextBoxFor(model => model.SomeString)</td>
</tr>
<tr>
<td>@Html.LabelFor(model => model.SomeBoolean)</td>
<td>@Html.CheckBoxFor(model => model.SomeBoolean)</td>
</tr>
...>

然后为了完成它,我在我的存储库中添加了一个 UpdateCollection(),显然,在从 DomainObj -> DataObj 映射之后,它在服务层中被调用。

public void SaveSettings(SaveDomainModel model)
{
var settings = MapDomainModelToList(model).AsQueryable();
_repository.UpdateCollection(settings);
}
private IEnumerable<DataObj> MapDomainModelToList(SaveDomainModel saveDomainModel)
{
var settings = new List<Setting>();

foreach (var domainModel in saveDomainModel.DomainModels)
{
var setting = GetSetting(domainModel.Key, saveDomainModel.SettingType);

if (!String.Equals(setting.Value, domainModel.Value, StringComparison.CurrentCultureIgnoreCase))
{
setting.Value = domainModel.Value;
setting.LastUpdated = DateTime.Now;
settings.Add(setting);
}
}

return settings;
}
public bool UpdateCollection(IQueryable<T> entities)
{
using (var transaction = _session.BeginTransaction())
{
foreach (var entity in entities)
{
_session.Update(entity);
}

transaction.Commit();
}
return true;
}

关于c# - 设计指南 - 来自数据库中松散类型键/值的动态 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20863855/

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