首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将继承的数据对象映射到相应的视图模型而不丢失其类型?

如何将继承的数据对象映射到相应的视图模型而不丢失其类型?
EN

Stack Overflow用户
提问于 2016-02-22 16:54:48
回答 2查看 689关注 0票数 1

假设我使用实体框架创建了一些类,这些类使用继承。例如:

代码语言:javascript
复制
namespace MyEntities
{
    Person
    Employee : Person
    Customer : Person
    WebCustomer : Customer
}

我还在另一个名称空间中使用了相同的类名作为视图模型的基础:

代码语言:javascript
复制
namespace ViewModels
{
    Person
    Employee : Person
    Customer : Person
    WebCustomer : Customer
}

然后,我可以做一些有趣的事情,比如使用通用方法创建一个已知类型的视图模型:

代码语言:javascript
复制
public T Make<T>(Entities.Person entity) where T : ViewModels.Person, new()
{
    T model = (T)new T().InjectFrom(entity);
    return model;
}

但我想不出该如何做的是,在我事先不知道类型的情况下,建立一个正确类型的模型--我希望能够这样做:

代码语言:javascript
复制
ViewModels.Person person = GetPersonById(24);

并让该person对象属于底层类型之一,比如一个WebCustomer。

这将允许我使用EditorFor和MVC.net中的DisplayFor模板来显示正确类型的人员的正确控件,即使只是按Id抓取一个。

我可以使用编辑器和显示模板,如果我允许实体泡到网站,但如果我想有映射逻辑一路我似乎不能得到正确的类型信息。

我想我们需要的是这样一种方法:

代码语言:javascript
复制
ViewModels.Person person Get(MyEntities entity)
{
// ??
}

返回的person对象按名称映射并转换为正确的基础类型。有什么方法可以实现这种行为吗?或者是否有更好的方法来处理通过模型映射器传递继承的结构,而我应该这样做呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-22 18:51:38

你只需要一个仿制工厂。以下面的代码为例:

代码语言:javascript
复制
public static PersonViewModelFactory
{
    public static TViewModel CreateFrom<TViewModel>(TEntity entity)
        where TViewModel : PersonViewModel, new()
    {
        return new TViewModel { // map properties from Person }
    }
}

然后,为了利用这个,你只需做:

代码语言:javascript
复制
var viewModel = PersonViewModelFactory.CreateFrom<CustomerViewModel>(person);

然后,viewModel将被键入为CustomerViewModel。但是,重要的是要认识到,您在这里使用的是最不常见的分母,所以即使您返回一个CustomerViewModel,您唯一可以利用的属性是存在于Person上的属性,而不是Customer。访问Customer属性的唯一方法是重载方法,将Customer的实例作为param,或者使实体param也是通用的。但是,如果两者都是通用的,那么它们都需要实现公共接口。这样,您可以将类型param限制在接口上,并访问接口定义的属性。

长和短,创建一个真正的通用类型映射器是一个痛苦。您要么接受我提到的方法的局限性,要么只为这种类型的事情使用现有的库,比如AutoMapper。毕竟,为什么要重新发明轮子呢?

票数 2
EN

Stack Overflow用户

发布于 2016-02-22 17:37:36

根据我们在评论中的讨论,是的,你是对的。如果您有确切的名称,您可以替换名称空间信息并使用Activator创建一个实例,前提是您的名称空间始终是一致的。

代码语言:javascript
复制
MyEntities entity
ViewModels.Person person = Activator.CreateInstance(
    Type.GetType("ViewModels" + "." + entity.GetType().Name));

然后,您可以创建动态映射,或者使用像EmitMapper这样的库在对象之间进行映射。

请记住,对这些类型的方法总是有一些性能上的损失。尽管如此,如果这是一个足够小的保证金,你对它感到满意,它将给你的动态方法,你正在寻找。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35559339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档