Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IInsert.ToDataTable报错的bug #227

Closed
feijie999 opened this issue Mar 11, 2020 · 37 comments
Closed

IInsert.ToDataTable报错的bug #227

feijie999 opened this issue Mar 11, 2020 · 37 comments

Comments

@feijie999
Copy link

image
在调用ExecutePgCopyAsync时发现报错,定位到ToDataTable方法引起的。实体中有部分字段为null引起,希望ToDataTable能兼容字段为可空类型

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

DataTable 不支持 null 字段,你觉得怎么处理这个好

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

如果内部处理, null 变成 0 可能不是用户想要的

@feijie999
Copy link
Author

实际项目中有些Entity字段是可为空的,所以定义如decimal?、DateTime?等。可否将此可空类型的值做一个判断如果为null,那么写入DataTable时类型就指定为System.DBNULL

@feijie999
Copy link
Author

ExecutePgCopyAsync是不是不支持自增Id

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

自增id支持需要怎么设置吗

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

实际项目中有些Entity字段是可为空的,所以定义如decimal?、DateTime?等。可否将此可空类型的值做一个判断如果为null,那么写入DataTable时类型就指定为System.DBNULL

ToDataTable 判断为 null 则报错提醒?对应的 ColumnInfo 设置为 decimal、DateTime 这样?

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

ExecutePgCopyAsync是不是不支持自增Id

fsql.Insert<T>().InsertIdentity().ExecutePgCopyAsync()

是不是说这样?

@feijie999
Copy link
Author

实际项目中有些Entity字段是可为空的,所以定义如decimal?、DateTime?等。可否将此可空类型的值做一个判断如果为null,那么写入DataTable时类型就指定为System.DBNULL

ToDataTable 判断为 null 则报错提醒?对应的 ColumnInfo 设置为 decimal、DateTime 这样?

image
不qued确定这也能否支持为null的情况

@feijie999
Copy link
Author

ExecutePgCopyAsync是不是不支持自增Id

fsql.Insert<T>().InsertIdentity().ExecutePgCopyAsync()

是不是说这样?

image
这也会提示Id不能为null。即使我手动赋值了longId的值也提示为null, x.Property(y => y.Id).IsIdentity(true);是设置了的

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

提示 id 不能为空是第一个问题,int? 这个问题。

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

dt.Columns.Add(col.Attribute.Name, typeof(int?));

这一行就会报错,dt 类型为 DataTable

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

if (val == null && col.Attribute.MapType.IsNullableType())
    throw new Exception($"[{didx}].{col.CsName} 值不可为 null;DataTable 限制不可使用 int?/long? 可空类型,IInsert.ToDataTable 将映射成 int/long,因此不可接受 null 值");

这个错误提示友好吗?

@feijie999
Copy link
Author

if (val == null && col.Attribute.MapType.IsNullableType())
    throw new Exception($"[{didx}].{col.CsName} 值不可为 null;DataTable 限制不可使用 int?/long? 可空类型,IInsert.ToDataTable 将映射成 int/long,因此不可接受 null 值");

这个错误提示友好吗?

强制要求用户把可空类型的字段变为不可空类型不太合适,使用pgcopy的场景也比较特殊,不如对pgcopy方法加一个字段来让用户自己决定是否接受将可空类型字段设置为默认值。

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

提示是要把值改为非 null,不是改类型

@feijie999
Copy link
Author

提示是要把值改为非 null,不是改类型

我刚刚试了下把值改为非null一样会报错,只有把类型改为非null才可以

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

是的,类型可以不改。这个要发一个 preview 新版本才行。

后面的提示内容应该看得懂吧,当你不知道机制的情况下?

@feijie999
Copy link
Author

是的,类型可以不改。这个要发一个 preview 新版本才行。

后面的提示内容应该看得懂吧,当你不知道机制的情况下?

只有这样解决了,DataTable不支持null感觉是一个bug。

@feijie999
Copy link
Author

自增长Id还是不支持pgcopy写入吗? await _freeSql.Insert(cranes).ExecutePgCopyAsync();提示说id不能为null。但是Id主键是不为null的long类型。

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

await _freeSql.Insert(cranes).InsertIdentity().ExecutePgCopyAsync()

这样试试

@feijie999
Copy link
Author

image
_freeSql.Insert(cranes).InsertIdentity().ExecutePgCopyAsync();
这些写也失败,当我手动将id赋值为1、2、3、4的时候能成功写入,但是默认值为0、0、0、0的时候抛异常。难道是pgcopy不支持自增长id

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

这个序列值可以计算出来,一般用 copy 导入会保留原始值才对

@feijie999
Copy link
Author

image
这里没有对自增Id列插入进行忽略吧?所以才会使用Entity的默认Id值?

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

要看 ToDataTable 的代码,默认不使用 id 的,我还打算默认使用 id。

InsertIdentity() 才会把 id 加入 dt 中

2881099 pushed a commit that referenced this issue Mar 11, 2020
- 优化 BulkCopy 对可空类型的属性处理;#227
2881099 pushed a commit that referenced this issue Mar 11, 2020
@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

v1.3.0-preview

  • 调整 移除对 System.ValueType 的依赖,减少版本冲突问题;(目前 FreeSql.dll 无任何公用库依赖)
  • 优化 IncludeMany 扩展方法对 T1 不自动迁移;
  • 优化 BulkCopy 默认插入自增键;
  • 优化 BulkCopy 对可空类型的属性处理;

最近的更新,升级可能有点影响,有问题继续在这里跟

@feijie999
Copy link
Author

要看 ToDataTable 的代码,默认不使用 id 的,我还打算默认使用 id。

InsertIdentity() 才会把 id 加入 dt 中

自增问题解决了,pgcopy只能我手动判断赋默认值了。感谢解答

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

优化 BulkCopy 对可空类型的属性处理;

这个我这边发布 1.3.0-preview6 解决了

@feijie999
Copy link
Author

  • 优化 BulkCopy 默认插入自增键;

默认加上 var dt = that.InsertIdentity().ToDataTable();后无法使用数据库的自增Id了。还是改回来吧,或者提供一个地方将_insertIdentity字段改为false

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

  • 优化 BulkCopy 默认插入自增键;

默认加上 var dt = that.InsertIdentity().ToDataTable();后无法使用数据库的自增Id了。还是改回来吧,或者提供一个地方将_insertIdentity字段改为false

意思就是默认用实体的自增值,是对的

@feijie999
Copy link
Author

  • 优化 BulkCopy 默认插入自增键;

默认加上 var dt = that.InsertIdentity().ToDataTable();后无法使用数据库的自增Id了。还是改回来吧,或者提供一个地方将_insertIdentity字段改为false

意思就是默认用实体的自增值,是对的

是的,之前是我忘记对数据库主键设置为自增了,尴尬了....

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

如果不加这个 InsertIdentity(),dt 得到的就没有 id 列信息。实际上 bulk 需要这个列的数据。

@feijie999
Copy link
Author

如果不加这个 InsertIdentity(),dt 得到的就没有 id 列信息。实际上 bulk 需要这个列的数据。

对于guid类型的Id可以加上InsertIdentity(),long或int的由数据库来维护自增比较好

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

如果不加这个 InsertIdentity(),dt 得到的就没有 id 列信息。实际上 bulk 需要这个列的数据。

对于guid类型的Id可以加上InsertIdentity(),long或int的由数据库来维护自增比较好

guid 默认可以,自增用 copy 是否确定可以触发数据库自增插入?可以的话我就还原这个功能

@feijie999
Copy link
Author

如果不加这个 InsertIdentity(),dt 得到的就没有 id 列信息。实际上 bulk 需要这个列的数据。

对于guid类型的Id可以加上InsertIdentity(),long或int的由数据库来维护自增比较好

guid 默认可以,自增用 copy 是否确定可以触发数据库自增插入?可以的话我就还原这个功能

copy确定可以出发数据库的自增插入

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

好的,那我去掉这个

@2881099
Copy link
Collaborator

2881099 commented Mar 11, 2020

v1.3.0-preview7

@feijie999
Copy link
Author

IJT4344K E3R%4Z6A_(2PIA
我刚刚尝试了下,这样的写法可以使DataTable插入为Null的值,首先判断属性类型是否为可空类型,如果是,那么就设置为不可空类型到Columns中,再赋值的时候发现值为null就写入DBNull.Value

@2881099
Copy link
Collaborator

2881099 commented Mar 13, 2020

IJT4344K E3R%4Z6A_(2PIA
我刚刚尝试了下,这样的写法可以使DataTable插入为Null的值,首先判断属性类型是否为可空类型,如果是,那么就设置为不可空类型到Columns中,再赋值的时候发现值为null就写入DBNull.Value

太好了,可以去掉那个异常提示

2881099 pushed a commit that referenced this issue Mar 13, 2020
2881099 pushed a commit that referenced this issue Mar 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants