4

我一直在尝试找到一种通过“视图”来展示对象的灵活方式。我可能最好通过示例来解释。

我有一个 Entity Framework 实体模型和一个可用于查询它的 Web 服务。我可以自己返回实体类,但这将包括一些我可能不想共享的字段 - 例如 ID,或来自实体模型中任何关联的 *Reference 属性。

我认为我需要的是数据视图,但我并不特别想为每个返回类型编写一个视图包装类。我希望我能够定义一个接口并以某种方式利用它。例如:

interface IPersonView
{
     string FirstName { get; }
     string LastName { get; }
}

-

// (Web service method)
IPersonView GetPerson(int id)
{
    var personEntity = [...];
    return GetView<IPersonView>(personEntity);
}

但是,为了做这样的事情,我必须让我的实体实现视图接口。我希望有一种更灵活的“鸭式”方法,因为一个对象可能有很多视图,我真的不想必须全部实现它们。

通过反映接口并复制字段和属性,我在构建动态类型方面取得了一些成功,但我无法将其转换回接口类型以便在 Web 服务上获得强类型。

只是寻找一些意见和建议,两者都会受到欢迎。谢谢。

4

2 回答 2

3

您不应该真正将实体直接传递给客户端,它们应该仅用于持久性。您应该引入针对您的 API 想要返回的任何数据量身定制的DTO/POCO ,例如

public class PersonDto
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

// public API method
public PersonDto GetPersonApi(int id)
{
    var personEntity = // pull entity from db
    return new PersonDto()
    {
        FirstName = personEntity.FirstName,
        LastName = personEntity.LastName
    };
}

这使您的持久层和公共接口之间保持清晰的分离。您可以使用AutoMapper之类的工具来完成数据映射方面的工作。只需在全局 asax 中设置一次映射:

protected void Application_Start()
{
    Mapper.CreateMap<Person, PersonDto>();
}
...
// public API method
public PersonDto GetPersonApi(int id)
{
    var personEntity = // pull entity from db
    return Mapper.Map<Person, PersonDto>(personEntity);
}
于 2013-01-24T14:39:29.213 回答
1

我通常会看到使用AutoMapper或类似工具完成此操作。它使相似类之间的映射变得更加简单。您仍然必须创建Views(在 MVC 上下文中将是 a Model),但只要您使用相同的字段名称,就会为您处理最繁琐的部分(映射)。

附带说明一下,如果您想更新数据,则需要共享 ID 和其他参考数据,因为您需要知道密钥才能知道要更新哪些记录。

于 2013-01-24T14:40:08.943 回答