我有一个带有几何列的空间表。我的实体如下:
public class Tile
{
public DbGeometry Geometry { get; set; }
}
我正在使用数据传输对象将Tile类返回给我的客户端。我还从我的客户端创建Tiles,所以我想从一个字符串(Geometry的Well Known Text表示)转换为DbGeometry字段。这是我的DTO:
public class TileDto
{
public String Geometry { get; set; }
}
现在我的第一个想法是创建自定义转换器,如下所示:
public class DbGeometryToStringConverter : ITypeConverter<DbGeometry, string>
{
public string Convert(ResolutionContext context)
{
var geom = (DbGeometry) context.SourceValue;
return geom.AsText();
}
}
public class StringToDbGeometryConverter : ITypeConverter<string, DbGeometry>
{
public DbGeometry Convert(ResolutionContext context)
{
var wkt = (string) context.SourceValue;
var geom = DbGeometry.FromText(wkt);
if (geom == null || !geom.IsValid) return null;
return geom;
}
}
然后我将AutoMapper配置设置为使用以下两者进行映射:
AutoMapper.Mapper.Initialize(cfg =>
{
// Configure our custom type converter for the DbGeometry class
cfg.CreateMap<DbGeometry, string>().ConvertUsing<DbGeometryToStringConverter>();
cfg.CreateMap<string, DbGeometry>().ConvertUsing<StringToDbGeometryConverter>();
cfg.CreateMap<Tile, TileDto>();
cfg.CreateMap<TileDto, Tile>();
});
但是这给了我错误:类型'System.String'没有默认构造函数
我尝试使用ResolveUsing方法,但它也给了我一个NullReferenceException。我确保所有列都有一个几何列,所以我不确定它是如何为空。
cfg.CreateMap<Tile, TileDto>()
.ForMember(tileDto => tileDto.Geometry,
map => map.ResolveUsing(tile => tile.Geometry.WellKnownValue));
这在Azure应用程序后端的ASP.NET应用程序中使用,因此调试器因错误而中断的控制器是:
public class TileController : TableController<TileDto>
{
private DatabaseContext _context;
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
_context = new DatabaseContext();
DomainManager = new TileDtoToTileMappedEntityDomainManager(_context, Request, Services);
}
public SingleResult<TileDto> GetTile(string id)
{
// MY ERROR HAPPENS HERE
return Lookup(id);
}
}
public class TileDtoToTileMappedEntityDomainManager : MappedEntityDomainManager<TileDto, Tile>
{
public override SingleResult<TileDto> Lookup(string id)
{
return LookupEntity(t => t.Id == id);
}
public override Task<TileDto> UpdateAsync(string id, Delta<TileDto> patch)
{
return UpdateEntityAsync(patch, id);
}
public override Task<bool> DeleteAsync(string id)
{
return DeleteItemAsync(id);
}
}
我正在使用AutoMapper 3.2.1,因为Azure Mobile Service SDK依赖于它。我正在尝试在我的Azure移动服务中为我的实体创建DTO,所以我不完全确定这是我的AutoMapper配置是错误的还是我的实体是如何设置的。我按照this post中的步骤创建了DTO。我需要在AutoMapper中进行配置更改才能使其正常工作吗?
答案 0 :(得分:1)
感谢@Backs,问题在于我的AutoMapper配置。使用MapFrom方法而不是ResolveUsing就可以了。
这是我的配置:
AutoMapper.Mapper.Initialize(cfg =>
{
cfg.CreateMap<Tile, TileDto>()
.ForMember(tileDto => tileDto.Geometry,
map => map.MapFrom(tile => tile.Geometry.AsText()));
cfg.CreateMap<TileDto, Tile>()
.ForMember(tile => tile.Geometry,
map => map.MapFrom(tileDto => DbGeometry.FromText(tileDto.Geometry)));
cfg.CreateMap<Tile, TileDto>();
cfg.CreateMap<TileDto, Tile>();
});