如何使用 Automapper 从 DbGeometry 转换为 String?
How to convert from DbGeometry to String using Automapper?
我有一个带有几何列的空间 table。我的实体如下:
public class Tile
{
public DbGeometry Geometry { get; set; }
}
我正在使用数据传输对象 return Tile class 给我的客户。我还从我的客户端创建了 Tiles,因此我想将字符串(几何图形的众所周知的文本表示形式)转换为 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>();
});
但这给了我错误:Type 'System.String' does not have a default constructor
我尝试使用 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 移动服务 SDK 依赖它。我试图在我的 Azure 移动服务中为我的实体创建 DTO,所以我不完全确定是我的 AutoMapper 配置有问题还是我的实体是如何设置的。我按照 this post 中的步骤创建了 DTO。我需要在 AutoMapper 中进行配置更改才能使其正常工作吗?
感谢@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>();
});
我有一个带有几何列的空间 table。我的实体如下:
public class Tile
{
public DbGeometry Geometry { get; set; }
}
我正在使用数据传输对象 return Tile class 给我的客户。我还从我的客户端创建了 Tiles,因此我想将字符串(几何图形的众所周知的文本表示形式)转换为 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>();
});
但这给了我错误:Type 'System.String' does not have a default constructor
我尝试使用 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 移动服务 SDK 依赖它。我试图在我的 Azure 移动服务中为我的实体创建 DTO,所以我不完全确定是我的 AutoMapper 配置有问题还是我的实体是如何设置的。我按照 this post 中的步骤创建了 DTO。我需要在 AutoMapper 中进行配置更改才能使其正常工作吗?
感谢@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>();
});