【问题标题】:Should NHibernate be responsible for mapping to viewmodels from domain objects?NHibernate 是否应该负责从域对象映射到视图模型?
【发布时间】:2013-06-24 05:51:50
【问题描述】:

我已经开始了一个新项目,并决定将 SharpArchitecture 与 Fluent nHibernate 一起用于我的 ORM。 (我以前从未使用过 nHibernate 或 SharpArchitecture,所以如果我遗漏了什么,请保持温和)

我正在尝试做的事情,我不确定这是否是正确的方法,或者是否可以使用 nHibernate 映射来获取域实体,比如说客户端并将其映射到更轻的 ClientModel,这将在我看来可以使用。较轻模型的原因是我不想为该视图带回客户端实体中的额外信息。

所以我的想法是在我的客户端实体之外创建一个只有几个字段的 ClientModel 实体,并使用 nHibernate 将两者映射在一起。

我尝试了一些方法,但都失败了。

我的问题 - 这是我应该使用 nHibernate 还是应该使用 automapper 之类的东西?我是否通过假设它不意味着它来混淆 nHibernate 中的单词映射?

在这里寻找一些 nHibernate 专家来帮助我。

我们也非常感谢您提供一个小样本。

这是一些代码。

public class Client : EntityWithTypedId<Guid>
    {
        public virtual String Name { get; set; }
        public virtual String Slug { get; set; }
        public virtual IList<Address> Addresses { get; set; }
        public virtual String ClientSize { get; set; }
        public virtual String Industry { get; set; }
        public virtual String Founded { get; set; }
        public virtual String Type { get; set; }
        public virtual String Specialty { get; set; }
        public virtual Boolean ShowOnWebsite { get; set; }
        public virtual Image Logo { get; set; }
        public virtual Image LogoBlackAndWhite { get; set; }
        public virtual Image LogoHighResolution { get; set; }
        public virtual String FacebookUrl { get; set; }
        public virtual String TwitterUrl { get; set; }
        public virtual String LinkedInUrl { get; set; }
        public virtual IList<Project> Projects { get; set; }
        public virtual IList<Tag> Tags { get; set; }
        public override Guid Id { get; protected set; }
        public virtual DateTime CreatedDate { get; set; }
        public virtual String CreatedBy { get; set; }
        public virtual DateTime ModifiedDate { get; set; }
        public virtual String ModifiedBy { get; set; }
        public virtual DateTime? DeletedDate { get; set; }
        public virtual String DeletedBy { get; set; }
    }

public class ClientViewModel
    {
        public virtual String Name { get; set; }
        public virtual String Slug { get; set; }
    }


public class ClientTasks : IClientTasks
    {
        private readonly IRepositoryWithTypedId<Client, Guid> _clientRepository;
        private readonly IRepositoryWithTypedId<Image, Guid> _imageRepository;
        public ClientTasks(IRepositoryWithTypedId<Client, Guid> clientRepository, IRepositoryWithTypedId<Image, Guid> imageRepository)
        {
            _clientRepository = clientRepository;
            _imageRepository = imageRepository;
        }

        public List<Client> GetAll()
        {
            var allClients = _clientRepository.GetAll().ToList();
            return allClients;
        }
}

【问题讨论】:

    标签: asp.net-mvc fluent-nhibernate fluent-nhibernate-mapping sharp-architecture


    【解决方案1】:

    听起来您对需要做的事情有一个很好的高级想法。您应该使用 NHibernate 向数据库发送和检索数据 - 而不是映射到客户端。 仅将您需要的数据发送回客户端。我是 Automapper 的粉丝,并使用它在数据对象和通过用户界面公开的视图模型之间进行映射。

    这是一个非常简单的示例,但假设您有一个帐户控制器,它将在视图中显示帐户信息。您可以使用以下内容从数据库中获取信息并将其映射到视图模型中

    public ActionResult Index(){
      var myAccount = _session.Get<Account>(1);
      var viewModel = _mapper.Map<Account,AccountViewModel>(myAccount);
      return View(viewModel);
    }
    

    在您的自动映射器映射文件中,设置如下内容:

     Mapper.CreateMap<Account, AccountViewModel>()
         .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.FullName))
         .ForMember(dest => dest.FirstName, opt => opt.MapFrom(src => src.FName));
    

    【讨论】:

    • 这是有道理的。所以我使用 IRepositoryWithTypedId 并将其传递给我的任务构造函数,但似乎无法弄清楚如何只选择某些字段?这可能吗?
    • 我没有使用过 SharpArchitecture,但是对于大多数存储库模式实现,您将拉回整个项目(大多数实现支持 Get、Save、FindAll 等)。除非有可查询的实现,否则您几乎会从数据库中拉回整个对象
    【解决方案2】:

    因此,为此我决定将任务层(仅返回完整对象的存储库)中的代码放入每个视图的查询类中(仅选择我想要的属性并将它们映射到我的 ViewModel)。

    此外,我决定通过 nhibernate 使用映射,因为选择特定列迫使我将字段从对象数组映射回我的域,所以我想既然我已经需要这样做,我不妨只使用 TransformUsing 方法也是。

    ClientListQuery.cs

    public IList<ClientListViewModel> GetClientListQuery()
            {
                ClientListViewModel clientListViewModel = null;
                return Session.QueryOver<Client>()
                    .OrderBy(o => o.Name).Asc
                    .SelectList(list => list
                    .Select(c => c.Id).WithAlias(() => clientListViewModel.Id)
                    .Select(c => c.Name).WithAlias(() => clientListViewModel.Name)
                    ...
                    .Select(c => c.Logo.Id).WithAlias(() => clientListViewModel.LogoId)
                    .Select(c => c.LogoBlackAndWhite.Id).WithAlias(() => clientListViewModel.LogoBlackAndWhiteId))
                    .TransformUsing(Transformers.AliasToBean<ClientListViewModel>())
                    .List<ClientListViewModel>();
            }
    

    客户端控制器

    [Transaction]
            public ActionResult Read([DataSourceRequest] DataSourceRequest request)
            {
                return Json(_clientListQuery.GetClientListQuery().ToDataSourceResult(request));
    
            }
    

    【讨论】:

      猜你喜欢
      • 2013-09-23
      • 1970-01-01
      • 1970-01-01
      • 2011-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-04
      • 1970-01-01
      相关资源
      最近更新 更多