关于SugarParameter的问题 返回

SqlSugar 沟通中
20 324
该叫什么 free 发布于1个月前
悬赏:0 飞吻

我使用的数据库是pgsql 没有使用postgis的情况下,现在有个字段在数据库中的类型是Point , 保存的值是 通过pgsql查询出来是(254,176) 类似这样的。

如果直接写sql插入的话,sql语句是 insert into locations local values ( POINT(1,2)) 这是正确的。

现在我通过sqlsugar,参数化插入保存信息的时候,通过SugarParameter去构造参数。

  //实体定义
  [SugarColumn(IsNullable = true, ColumnDataType ="point",SqlParameterDbType =typeof(PointConverter))]
  public CooPoint Point { get; set; }
 
 //自定义转换方法
 
 public class PointConverter : ISugarDataConverter
 {
     public SugarParameter ParameterConverter<T>(object columnValue, int columnIndex)
     {
         var val = (CooPoint)columnValue;
         var res = new SugarParameter($"@myp{columnIndex}", val.ToSqlString(),System.Data.DbType.Object);
         return res;
     }

     public T QueryConverter<T>(IDataRecord dataRecord, int dataRecordIndex)
     {
         if (typeof(T) == typeof(CooPoint))
         {
             var val = dataRecord.GetValue(dataRecordIndex);
             if (val == null || val == DBNull.Value)
             {
                 return default;
             }
             string[] valStr = val.ToString().Replace("(","").Replace("(", "").Split(",");
             return (T)(object)new CooPoint
             {
                 X = double.Parse(valStr[0]),
                 Y = double.Parse(valStr[1])
             };
         }
         return default;
     }
 }
 //这个是类型
  public struct CooPoint
 {
     public double X { get; set; }
     public double Y { get; set; }

     public override string ToString() => $"({X},{Y})";

     public object ToSqlString() => $"POINT({X},{Y})";
 }

现在存在的问题是,在执行  _dbContext.Insertable(entity)  时,生成的sql语句始终是 insert into locations local values ( N'POINT(1,2)' )

有什么办法可以让生成的sql语句变成  insert into locations local values ( POINT(1,2)) 吗?

热忱回答20

  • fate sta fate sta VIP0
    1个月前

    https://www.donet5.com/Home/Doc?typeId=1221


    pgsql支持  geometry / postgis


    看标题4 ,不需要自定义

    0 回复
  • free free VIP0
    1个月前

    pgsql中没有安装postgis,也可以使用 point吗?


    @fate sta

    0 回复
  • fate sta fate sta VIP0
    1个月前

      public class NoParameterCommonPropertyConvert : ISugarDataConverter
      {
          public SugarParameter ParameterConverter<T>(object columnValue, int columnIndex)
          {
              if (columnValue == null) 
              {
                  new SugarParameter("null", null, null);
              }
              return new SugarParameter(columnValue+"", null, null);
          }
          public T QueryConverter<T>(IDataRecord dr, int i)
          {
              var value = dr.GetValue(i);
              return (T)UtilMethods.ChangeType2(value, typeof(T));
          }
      }


    可以参考这个无参数化的

    0 回复
  • fate sta fate sta VIP0
    1个月前

    继承 NoParameterCommonPropertyConvert value就是无参数化的,也可以直接使用typeof(NoParameterCommonPropertyConvert )

    0 回复
  • free free VIP0
    1个月前

    @fate sta: 

    insert into locations ("point") VALUES ('POINT(1.121323123,1.123123)')  改完以后是这样的,也无法满足要求,我需要的结果是:insert into locations ("point") VALUES (POINT(1.121323123,1.123123))   注意POINT附近是没有'的。这个可以实现吗?


    0 回复
  • fate sta fate sta VIP0
    1个月前

    @free:我处理一下

    0 回复
  • fate sta fate sta VIP0
    1个月前

    image.png

    我测试正常的,你是不是SQLSUGAR版本太低

    0 回复
  • free free VIP0
    1个月前

    现在的版本是5.4.175.使用5.1.4.176-preview16是正确的吗?

    0 回复
  • free free VIP0
    1个月前

    @fate sta现在的版本是5.4.175.使用5.1.4.176-preview16是正确的吗?

    0 回复
  • fate sta fate sta VIP0
    1个月前

    @free:升级最新测试,还有问题,提供完整可以重现的DEMO,可以不用库只要能生成SQL

    0 回复
  • 抱走 抱走 VIP0
    1个月前

    这种情况,如果可以有多一个方法  

    _dbContext

        .Insertable(entity)

        .ModifyColumn(it=>it.Point == ExtSqlFunc.Point(it.OtherIgnorePoint.x, it.OtherIgnorePoint.y))    // 类似setColumn这样的额外修改某属性就方便好多了


    或者

    ParameterConverter<T>(object columnValue, int columnIndex) 这个方法可以多传一个参数吗?把整个Entity对象传进去,可能参数的value是来自 Entity的其他属性一起处理的结果



    @fate sta

    0 回复
  • free free VIP0
    1个月前

    test.zip

    使用最新版本的同样存在这个问题,应该是我的写法有问题吧,先谢谢作者

    0 回复
  • free free VIP0
    1个月前

    @fate sta使用最新版本的同样存在这个问题,应该是我的写法有问题吧,感谢

    test.zip

    0 回复
  • fate sta fate sta VIP0
    1个月前

    直接用 NoParameterCommonPropertyConvert 

    0 回复
  • fate sta fate sta VIP0
    1个月前

    这个是现成的

    0 回复
  • free free VIP0
    1个月前

    @fate sta:我尝试了三种情况 

    1、

     public class locations
     {
         [SugarColumn(IsNullable = true, ColumnDataType = "point", SqlParameterDbType = typeof(NoParameterCommonPropertyConvert))]
         public CooPoint point { get; set; }
     }
    
     public class CooPoint
     {
         public double X { get; set; }
         public double Y { get; set; }
         public override string ToString() => $"POINT({X},{Y})";
     }

    这种情况下,重写了ToString方法后, 生成的insert 语句是没有问题的,但是查询存在问题

    2、

     public class locations
     {
         [SugarColumn(IsNullable = true, ColumnDataType = "point", SqlParameterDbType = typeof(PointConverter))]
         public CooPoint point { get; set; }
     }
    
    public class PointConverter: ISugarDataConverter
    {
        public SugarParameter ParameterConverter<T>(object columnValue, int columnIndex)
        {
            if (columnValue == null)
            {
                new SugarParameter("null", null, null);
            }
    
            return new SugarParameter(columnValue?.ToString() ?? "", null, null);
        }
    
        public T QueryConverter<T>(IDataRecord dr, int i)
        {
            object value = dr.GetValue(i);
            return (T)UtilMethods.ChangeType2(value, typeof(T));
        }
    }

    这种情况,是我将NoParameterCommonPropertyConvert的实现直接复制到 PointConvert中,准备尝试实现一下QueryConvert,但是直接复制代码到新的实现中,发现的问题是生成的insert语句同样是错误的


    生成的insert语句错误

    image.png

    3、

     public class locations
    {
        [SugarColumn(IsNullable = true, ColumnDataType = "point", SqlParameterDbType = typeof(PointConverter))]
        public CooPoint point { get; set; }
    }
      
     public class PointConverter : ISugarDataConverter
     {
         public SugarParameter ParameterConverter<T>(object columnValue, int columnIndex)
         {
             var val = (CooPoint)columnValue;
             var res = new SugarParameter($"params_{columnIndex}", val.ToSqlString(), typeof(NoParameterCommonPropertyConvert));
             return res;
         }
         public T? QueryConverter<T>(IDataRecord dataRecord, int dataRecordIndex)
         {
             if (typeof(T) == typeof(CooPoint))
             {
                 var val = dataRecord.GetValue(dataRecordIndex);
                 if (val == null || val == DBNull.Value)
                 {
                     return default;
                 }
                 string[] valStr = val.ToString().Replace("(", "").Replace("(", "").Split(",");
                 return (T)(object)new CooPoint
                 {
                     X = double.Parse(valStr[0]),
                     Y = double.Parse(valStr[1])
                 };
             }
             return default;
         }
     }

    这种情况下,我尝试在自己实现 ISugarDataConverter中传入 NoParameterCommonPropertyConvert,得到的结果如下:

    image.png

    这也是错误的。

    我的使用姿势有问题吗?

    0 回复
  • fate sta fate sta VIP0
    1个月前

    image.png

    这个是有参数的 

     你用继承isugardata肯定是错的

    要继承

    NoParameterCommonPropertyConvert

    并且升级最新预览版本

    0 回复
  • fate sta fate sta VIP0
    1个月前

    升级最新预览版本

    你可以重写

    NoParameterCommonPropertyConvert

    0 回复
  • fate sta fate sta VIP0
    1个月前
      
     public class PointConverter : NoParameterCommonPropertyConvert
     {
         public SugarParameter ParameterConverter<T>(object columnValue, int columnIndex)
         {
             var val = (CooPoint)columnValue;
             //按我这边改
             var res = new SugarParameter(val.ToSqlString(),null, typeof(NoParameterCommonPropertyConvert));
             return res;
         }
         public T? QueryConverter<T>(IDataRecord dataRecord, int dataRecordIndex)
         {
             if (typeof(T) == typeof(CooPoint))
             {
                 var val = dataRecord.GetValue(dataRecordIndex);
                 if (val == null || val == DBNull.Value)
                 {
                     return default;
                 }
                 string[] valStr = val.ToString().Replace("(", "").Replace("(", "").Split(",");
                 return (T)(object)new CooPoint
                 {
                     X = double.Parse(valStr[0]),
                     Y = double.Parse(valStr[1])
                 };
             }
             return default;
         }
     }

    升级预览版本 23

    这样就对了

    0 回复
  • free free VIP0
    1个月前

    @fate sta:楼主牛逼,确实可以了

    0 回复