将AutoMapper与WCF数据服务和EF4集成的最佳实践

时间:2010-11-29 19:34:24

标签: c# .net entity-framework-4 automapper wcf-data-services

我们正在通过WCF数据服务公开域模型。该模型源自EF4,需要一些额外的工作才能使其成为通过网络服务发布所需的形式。

我想在EF4之外处理这个问题,以保持我们的EDMX专注于模型而不是它的用法。我的想法是创建一个专门用于Web服务的自定义“ServiceModel”,并包含特定于服务的问题。

我的问题是如何在WCF数据服务中间最好地连接自动播放器。我正在使用WCF数据服务与ServiceModel的自定义(基于反射)提供程序。我在哪里可以将OData查询(对于ServiceModels)转换为EF4查询(对于DomainModels),并将结果映射回ServiceModels?

2 个答案:

答案 0 :(得分:21)

我在WCF服务中使用Automapper从数据库实体映射到数据协定。对于每个服务,我使用InitializeMap的方法创建一个静态AutomapBootstrap类。然后,对于每个服务,我使用AutomapServiceBehavior属性修饰服务。

我不知道这是否适用于您的场景,因为WCF数据服务与使用WCF WebBindings的vanilla WCF SOAP服务和服务略有不同。

然而,值得一看。

这是服务行为

[CoverageExclude(Reason.Framework)]
public sealed class AutomapServiceBehavior : Attribute, IServiceBehavior
{
    public AutomapServiceBehavior()
    {
    }

    #region IServiceBehavior Members

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, 
        Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
        AutomapBootstrap.InitializeMap();
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
    {
    }

    public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
    {
    }

    #endregion
}

这是我的映射器

public class AutomapBootstrap
{
    public static void InitializeMap()
    {
        Mapper.CreateMap<CreateBookmarkRequest, TagsToSaveRequest>()
            .ForMember(dest => dest.TagsToSave, opt => opt.MapFrom(src => src.BookmarkTags))
            .ForMember(dest => dest.SystemObjectId, opt => opt.UseValue((int)SystemObjectType.Bookmark))
            .ForMember(dest => dest.SystemObjectRecordId, opt => opt.Ignore());

    }
}

这就是我将服务连接到automap的方式

[AutomapServiceBehavior]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Clouds : ICloudService
{ 
    // service operation implementation details elided
}

最后请注意,我的服务是一个使用WebBinding的vanilla WCF服务,并以REST风格的方式提供数据。

答案 1 :(得分:0)

除非您的域模型非常简单且非常浅(其中很少有集合),否则我建议您不要将域对象投影到构建服务(DTO)层。

相反,我会直接从您的数据存储(DB)投影您的DTO。如果不这样做会导致许多SELECT N + 1问题,并且最终维护成本比直接从数据库表中直接补充DTO更昂贵。