将 AutoMapper 与 EF6 DbFirst 和存储过程(复杂类型)结合使用

Using AutoMapper with EF6 DbFirst and Stored Procedure (complex types)

我正在使用 Entity Framework 6 DBFirst、MVC5 和 AutoMapper。

我有 2 个表,Customers 和 CustomerContacts 对于我在 Entity Framework EDMX(自动生成)中的每个 class,我都有一个具有完全相同属性的模型 class。即 Customer => Model.Customer、CustomerContact => Model.CustomerContact。这就是我使用 AutoMapper 的原因。

问题 1:由于我的 Customer_Get 存储过程 returns 是一个自动生成的复杂类型 (Customer_Get_Result),大多数人会为此创建一个额外的模型 class还? (Model.Customer_Get_Result.cs) 或者所有的属性都应该合并添加到 Model.Customer?

问题 2:我处理以下客户联系人映射的方式是否正确?大多数 Model.Customer 中的每个 属性 都与自动生成的 EF6 DBFirst 文件完全相同,除了我放在 Model.Customer:

中的文件
public List<CustomerContact> Contacts { get; set; }

最后我希望能够使用 Customer.Contacts 自动获取所有客户联系人的列表

在我的 AutoMapper 中,我正在尝试做这样的事情,但我认为这是不正确的:

    CreateMap<Customer, Model.Customer>()
        .ForMember(dest => dest.Contacts, opt => opt.MapFrom(src => src.CustomerContact));

    //map for customer getlist stored proc which will be returning several fields
    //such as TotalCount, RowNumber, fields from a bunch of other tables
    CreateMap<Customer_Get_Result, Model.Customer>();

For a stored procedure's complex type (Customer_Get_Result) would most people make an additional model class for this also?

如果它的属性与 Customer 完全相同,那么我可能不会只为它创建模型,而是将它映射到现有模型。

虽然这取决于您使用此模型做什么 class,以及从实体映射的数据的用例是否与从存储过程映射的数据有任何不同。模型只是 POCO 的一个奇特术语。模型通常是两件事之一。实体的简化,比 EF 实体更接近 POCO;例如您可能在业务层和数据库层之间使用的 DTO。或者它是针对特定上下文的专门化,例如仅具有特定视图所需属性的 ViewModel,并且通常包括 UI 特定的数据注释等内容。

这在很大程度上取决于您的应用程序是如何分层的,应用程序的哪一部分正在检索数据,以及它打算如何处理这些数据。就是说,我可能会从使用相同的模型开始,然后看看我是否觉得需要稍后进行分解(但您仍然需要 2 个映射,一个来自 SP_Complex_Type -> 模型,一个来自实体 ->型号).

看起来您的 DB/EF 模型只有一个来自 Customer.CustomerContact 的相关联系人,但您的模型具有一对多关系 Model.Customer.Contacts。我仅基于 属性 名称的复数,因为您没有向我们提供您的实体的任何声明。无论哪种方式,您的 EF 实体支持的关系与您的模型支持的关系不匹配。您可以使用 AutoMapper 在这里做很多不同的事情,但是在您弄清楚为什么一个有相关联系人列表而另一个只有一个相关联系人之前,您无法做出决定。

CreateMap<Customer, Model.Customer>()
        .ForMember(dest => dest.Contacts, opt => opt.MapFrom(src => src.CustomerContact));

当将一个列表映射到一个列表,并且属性的命名不同时,上面的操作正是您要做的。此外,如果每个列表中的类型不同,那么您需要确保您之前也为这些类型声明了一个映射。例如,如果你要从 List<CustomerContactEntity>List<CustomerContactModel> 那么你需要已经完成 CreateMap<CustomerContactEntity,CustomerContactModel> 来告诉 AutoMapper 它可以转换这些类型。这样当它遇到列表中的每个项目时,它会看到它具有该子类型的映射。