Невозможно использовать SqlGeography в качестве параметра для ядра Dapper и ASP.NET - PullRequest
0 голосов
/ 08 октября 2018

Я пытаюсь вставить тип данных 'география' в SQL Server, используя Dapper 1.50.2 с ASP.NET Core 2.1.

Я читал в нескольких потоках, что ондолжно быть принято по умолчанию, начиная с 1.32 , но я получаю исключение при попытке вставить тип данных.

Примечание: я использую не .NET CORE Тип данных в моей сущности.Microsoft.SqlServer.Types: 14.0.1016.290, поскольку я не смог найти хороший тип географии, совместимый с ядром .NET. (что-то с EF Core)

Entity:

public class Address : Entity{
    /* .. */
    public SqlGeography SpatialLocation { get; set; }
    /* .. */
}

Метод вставки (стандартный):

public virtual TEntity Insert(TEntity entity){
    if (string.IsNullOrEmpty(entity.CreationUser)){
        entity.CreationUser = "UNKNOWN";
    }

    if (entity.EndDate == default(DateTime)){
        entity.EndDate = DateTime.MaxValue;
    }

    return (TEntity) DapperExtensionsProxy.Insert(entity);
}

Метод вставки (специализированный):

public override Address Insert(Address entity){
    if (entity == null){
        throw new ArgumentNullException(nameof(entity));
    }

    var sql = $"INSERT INTO [dbo].[Address]"
                  + "([CreationDate]"
                  + ",[StartDate]"
                  + ",[UpdateDate]"
                  + ",[EndDate]"
                  + ",[CreationUser]"
                  + ",[UpdateUser]"
                  + ",[CityId]"
                  + ",[Street]"
                  + ",[Street2]"
                  + ",[SpatialLocation]"
                  + ",[Flags])"
              + "VALUES"
                  + "(@creationDate"
                  + ",@startDate"
                  + ",@endDate"
                  + ",@creationUser"
                  + ",@cityId"
                  + ",@street"
                  + ",@street2"
                  + ",@spatial"
                  + ",@flags);";        

    DapperExtensionsProxy.Execute(sql, new
    {
        creationDate = entity.CreationDate,
        startDate = entity.StartDate,
        endDate = entity.EndDate,
        creationUser = entity.CreationUser,
        cityId = entity.CityId,
        street = entity.Street,
        street2 = entity.Street2,
        flags = entity.Flags,
        spatial = entity.SpatialLocation
    });

    /* should get ID back, check with SELECT SCOPE_IDENTITY() */

    return entity;
}

Я также попробовал подход с динамическими параметрами с помощью dapper (из первого поста), но я не уверен, как применять их вместе с различными параметрами

Exception

The member spatial of type Microsoft.SqlServer.Types.SqlGeography cannot be 
used as a parameter value

ОБНОВЛЕНИЕ

Я решил эту проблему путем обхода этого фрагмента кода.Правильный синтаксис оказался трудным.

public override Address Insert(Address entity){
    if (entity == null){
        throw new ArgumentNullException(nameof(entity));
    }

    var sql = $"INSERT INTO [dbo].[Address]"
              + "([CreationDate]"
              + ",[StartDate]"
              + ",[EndDate]"
              + ",[CreationUser]"
              + ",[CityId]"
              + ",[Street]"
              + ",[Street2]"
              + ",[SpatialLocation]"
              + ",[Flags])"
              + "VALUES"
              + "(@creationDate"
              + ",@startDate"
              + ",@endDate"
              + ",@creationUser"
              + ",@cityId"
              + ",@street"
              + ",@street2"
              + ",@spatial "
              + ",@flags); "
              + "SELECT SCOPE_IDENTITY()";

    string lat = entity.SpatialLocation.Lat.Value.ToString(CultureInfo.InvariantCulture);
    string longitude = entity.SpatialLocation.Long.Value.ToString(CultureInfo.InvariantCulture);
    entity.Id = DapperExtensionsProxy.ExecuteScalar<int>(sql,new{
                                                             creationDate = entity.CreationDate,
                                                             startDate = entity.StartDate,
                                                             endDate = entity.EndDate,
                                                             creationUser = entity.CreationUser,
                                                             cityId = entity.CityId,
                                                             street = entity.Street,
                                                             street2 = entity.Street2,
                                                             flags = entity.Flags,
                                                             spatial = $"POINT({lat} {longitude} 4326)"
                                                         });
    return entity;
}
...