【发布时间】:2019-07-06 07:08:21
【问题描述】:
我有一个简单的要求,我正在努力实现。基本上,我有一个填充了企业列表的视图。企业列表的属性体现在我的视图模型类中,该类又绑定到视图。这是一个带有业务列表的简单 MVC 应用程序。
但是,我遇到的问题是我为另一个依赖于视图模型的类派生了业务列表,它基本上类似于我称为 BusinessService 的存储库。繁忙的服务由异步方法组成,这是我的困境,当从 viewModel 的 Ctor 或属性的 getter 进行调用时,我的应用程序挂起。该调用也是对业务服务中的 EF 数据库的异步调用,并且不确定对此的正确方法是什么。请看下面的代码:
视图模型:
#region Ctor
public BusinessListViewModel(IBusinessService businessService, IStringBuilder builder)
{
_businessService = businessService;
_builder = builder;
InitBusinesses().Wait(); //OPTION 1
}
#endregion
#region Properties
public IEnumerable<BusinessViewModel> _businesses;
public IEnumerable<BusinessViewModel> Businesses
{
get
{
if (_businesses == null)
{
InitBusinesses().Wait(); //OPTION 2
}
return _businesses;
}
set => _businesses = value;
}
private async Task InitBusinesses()
{
var response = await _businessService.Get();
Businesses = response.IsSuccessful
? response.Data.Select(p => new BusinessViewModel(_builder, p))
: new List<BusinessViewModel>();
}
商业服务:
#region Service Methods
public async Task<Response<IEnumerable<Models.Business>>> Get()
{
var data = await Db.Businesses.ToListAsync();
return new Response<IEnumerable<Models.Business>>
{
IsSuccessful = true,
Message = "Successful",
Data = Mapper.Map<List<Models.Business>>(data)
};
}
请您建议最好的模式和正确的方法,我已经知道这是错误的>谢谢
【问题讨论】:
-
您询问的两个选项都不好。属性不应加载数据。方法应该加载数据。属性应该包含有关对象的信息,而不是从其他来源加载数据的一种方式。在设计用于封装信息(模型)的数据与设计用于检索该信息的逻辑(数据层)之间保持明显的分离
-
@mason 谢谢你的回复,如上所述,我已经明白这不是正确的方法。根据您的解释,即使使用工作单元和存储库模式,您将如何填充属性以绑定到用户界面?
-
不要让视图模型这样做。让外面的代码来做。它通常看起来像
var myViewModel = new MyViewModel(); myViewModel.Businesses = await _repository.GetBusinessesAsync(); -
@mason 正是我出错的地方,我试图让我的控制器尽可能薄,但我认为这种方式最有意义。
标签: c# asp.net-mvc entity-framework asynchronous async-await