无名商城论坛

搜索
查看: 229|回复: 0

[其他技术] 【LSP】SqlSugar ORM框架之找不到主键问题

[复制链接]

1万

主题

1万

帖子

3万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
32464
发表于 2022-5-8 17:02:30 | 显示全部楼层 |阅读模式


前端时间在.NetCore项目中使用SqlSugar ORM框架(引用sqlSugarCore依赖包)的时候遇到了一个奇葩问题:对表进行数据更新操作的时候,报错 “ You cannot have no primary key and no conditions ”,即没有主键和条件的报错。

由于当时采用的更新方式是UpdateColumns()+WhereColumns(),所以排除了没有条件的问题,定位问题:缺少主键。

SqlSugar框架在初始化DB对象时,为我们提供了两种获取主键的方式:

SqlSugarClient属性:InitKeyType   

1.SysTable  表示通过数据库系统表查询表主键,这种需要数据库最高权限,并且数据库表需有主键或能获取到主键。  

2.Attribute 表示通过实体  [SugarColumn(IsPrimaryKey = true)]标签获取主键,而无需通过数据库表。

在项目中我们并未指定InitKeyType属性值,也就是默认使用了 SysTable模式。

于是,首先查看数据表设计结构,发现表结构是有主键的,当时就懵逼了。。。赶紧去看了一下SqlSugar源码,发现ORM框架中是通过如下方式获取主键列的。
数据库中直接查询如上sql语句,发现并未找到主键列(IsPrimaryKey=1),神奇了。。。表结构明明有主键却查不到,折腾了一会儿才知道,项目中用的数据表竟然是同义词!!!

同义词是指向其他数据库表的别名,在当前数据库根本无法获取同义词对应的表结构属性,到这里也就恍然大悟了,原来是同义词导致框架SysTable模式下获取不到表主键。

执行框架中的如上Sql,还有其他几种情况会导致无法获取到主键:

1)表没建主键

2)表使用的同义词

3)当前数据库用户没有查询系统表sys级别权限

4)数据库排序规则:_CI(CS) 是否区分大小写,CI不区分,CS区分

    如果设置的区分大小写,则上面sql中的如下部分将受影响,导致找不到数据。数据库实际存的值是大写的U,V

SELECT id
                         FROM sysobjects
                         WHERE xtype IN('u',
                                        'v')


解决方案:

1)SqlSugar也支持手写sql语句,直接手写更新sql即可。

2)初始化SqlSugarClient DB对象时,选择InitKeyType.Attribute模式,通过实体特性获取主键。



后续:

项目中问题虽然解决了,但是后来还是比较好奇:使用了WhereColumns()条件列,为什么还要去找主键呢?直接根据条件列更新不可以么???于是决定一探究竟。。。

定位到获取主键的方法:
我们会发现ExecuteCommandAsync异步方法中,不再通过复制异步更新对象的方式,而是直接采用了当前调用的更新对象UpdateableProvider,该对象已实现WhereColumnList属性赋值。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表