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

C# AutoMapper与WCF数据服务和EF4集成的最佳实践,c#,.net,entity-framework-4,automapper,wcf-data-services,C#,.net,Entity Framework 4,Automapper,Wcf Data Services,我们正在通过WCF数据服务公开一个域模型。该模型源于EF4,需要一些额外的工作才能将其转换为所需的形式,以便通过web服务发布 我希望在EF4之外处理这个问题,以使我们的EDMX专注于模型,而不是它的使用。我的想法是创建一个定制的“ServiceModel”,它专门用于web服务,并包含特定于服务的关注点 我的问题是如何最好地在WCF数据服务的中间连接自动机。我将WCF数据服务与ServiceModels的自定义(基于反射的)提供者一起使用。我在哪里可以将OData查询(对于ServiceMod

我们正在通过WCF数据服务公开一个域模型。该模型源于EF4,需要一些额外的工作才能将其转换为所需的形式,以便通过web服务发布

我希望在EF4之外处理这个问题,以使我们的EDMX专注于模型,而不是它的使用。我的想法是创建一个定制的“ServiceModel”,它专门用于web服务,并包含特定于服务的关注点


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

我在WCF服务中使用Automapper从数据库实体映射到数据契约。对于每个服务,我都创建了一个静态AutomapBootstrap类,其中包含一个初始化映射的方法。然后,对于每个服务,我用AutompServiceBehavior属性装饰服务

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

然而,它值得一看

这是服务行为

[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());

    }
}

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

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


相反,我会直接从数据存储(DB)中投影DTO。如果不这样做,将导致许多SELECT N+1问题,并最终导致维护成本高于直接从数据库表中水合DTO

非常有用的代码片段,如果可以包含所需的名称空间,可能会变得更好-我花了更长的时间来找出这些名称空间,而不是理解代码。哪些对象/名称空间最容易混淆?所需的名称空间是System.ServiceModel、System.ServiceModel.Channel,System.ServiceModel.Description和System.Collections.ObjectModel请注意,AddBindingParameter方法针对为您的服务配置的每个侦听uri运行。来自MSDN:“此方法对每个侦听URI调用一次。例如,如果一个服务有四个端点,其中两个具有相同的侦听URI,则此方法将被调用三次”。我已尝试实现此解决方案,但无法使其工作。我知道正在调用Mapper.Initialize函数,因为我可以单步执行它,但是当调用Mapper.Map时,我会遇到标准的AutoMapper“unsupported typemap”错误。有什么建议吗?
[AutomapServiceBehavior]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Clouds : ICloudService
{ 
    // service operation implementation details elided
}