ClickHouse / ClickHouse/ClickHouse.EntityFrameworkCore
SaveChanges fails for value-converted properties: bulk insert path does not apply the converter
- Ngôn ngữ chính
- C#
- Star
- 23
- Fork
- 7
- Merge trung bình
- 14 ngày 3 giờ
- Pull request đã merge (30 ngày)
- 1
Mô tả
## Problem
`SaveChanges` fails for every property that has a value converter. The bulk insert path sends the model value to the driver. It does not apply the converter from the type mapping.
`src/EFCore.ClickHouse/Update/Internal/ClickHouseModificationCommandBatch.cs:104`:
```csharp
row[i] = writeColumns[i].Value ?? DBNull.Value;
```
`IColumnModification.Value` gives the model-level value. The code never calls `RelationalTypeMapping.Converter`, so the driver receives a CLR type that it cannot write to the column.
## Effect
C# enums are affected. The README documents enums as a supported type (`README.md`, type mapping table), and the provider maps them on purpose with `ClickHouseEnumTypeMapping` + `EnumToStringConverter`. Enum inserts fail.
Any property with an explicit `HasConversion(...)` is also affected.
## How to reproduce
```csharp
public enum Colour { Red, Green, Blue }
public class Row
{
public long Id { get; set; }
public Colour Colour { get; set; }
}
// ...
await ctx.Database.EnsureCreatedAsync(); // creates: colour String
ctx.Rows.Add(new Row { Id = 1, Colour = Colour.Green });
await ctx.SaveChangesAsync(); // throws
```
Error:
```
ClickHouse.Driver.Copy.ClickHouseBulkCopySerializationException : Error when serializing data
---- System.ArgumentException : String requires string, byte[], ReadOnlyMemory, or Stream, got Colour
at ClickHouse.Driver.Types.StringType.Write(ExtendedBinaryWriter writer, Object value)
at ClickHouse.Driver.Copy.Serializer.RowBinarySerializer.Serialize(Object[] row, ClickHouseType[] types, ExtendedBinaryWriter writer)
```
Confirmed against a real ClickHouse server for `enum`, `Uri`, and `DateTimeOffset`.
## Why queries are not affected
The query parameter path goes through `RelationalTypeMapping.CreateParameter`, which applies the converter. Only the insert path skips it.
## Suggested fix
Apply the converter when the row is built, for example with `ConvertToProvider` from the column type mapping.
Also add `SaveChanges` test coverage for an enum property, a `Uri` property, and a property with an explicit `HasConversion`. The current enum tests only assert converter behaviour on the mapping object. They never do an insert, which is why this defect was not found.
## Notes
Found while I investigated #53. The two problems are independent. #53 does not need this fix, because a native `DateTimeOffset` mapping carries no converter.
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Hướng nghiên cứu
Bắt đầu tại src/EFCore.ClickHouse/Update/Internal/ClickHouseModificationCommandBatch.cs ở dòng 104 và kiểm tra cách lấy giá trị của hàng từ ánh xạ kiểu cột. Thêm coverage cho SaveChanges đối với các thuộc tính enum, Uri và HasConversion tường minh, sau đó xác minh các insert theo các ánh xạ được ghi lại trong tài liệu và với một máy chủ ClickHouse thực nếu có thể. Hoàn thành có nghĩa là các giá trị provider đã chuyển đổi đến được driver và các kiểm thử mới đều đạt.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- csharp
- Lĩnh vực
- database
- Loại issue
- Lỗi
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức độ hoạt động
- Ít trao đổi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức phù hợp với người mới
- 76/100