C# AutoMapper与WCF数据服务和EF4集成的最佳实践
我们正在通过WCF数据服务公开一个域模型。该模型源于EF4,需要一些额外的工作才能将其转换为所需的形式,以便通过web服务发布 我希望在EF4之外处理这个问题,以使我们的EDMX专注于模型,而不是它的使用。我的想法是创建一个定制的“ServiceModel”,它专门用于web服务,并包含特定于服务的关注点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数据服务的中间连接自动机。我将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
}