Skip to content

Commit ff9fb29

Browse files
committed
Fixed decimal parameter type mismatch in bulk updates
1 parent b1c320d commit ff9fb29

File tree

3 files changed

+94
-70
lines changed

3 files changed

+94
-70
lines changed
Lines changed: 61 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,90 @@
1-
using Ivy.Data.BigQuery;
1+
using Ivy.Data.BigQuery;
22
using Ivy.EntityFrameworkCore.BigQuery.Storage.ValueConversion.Internal;
33
using Microsoft.EntityFrameworkCore.Storage;
4-
using System;
5-
using System.Collections.Generic;
4+
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
65
using System.Data.Common;
76
using System.Globalization;
8-
using System.Linq;
9-
using System.Text;
10-
using System.Threading.Tasks;
117

12-
namespace Ivy.EntityFrameworkCore.BigQuery.Storage.Internal.Mapping
13-
{
14-
public class BigQueryDecimalTypeMapping : RelationalTypeMapping
15-
{
8+
namespace Ivy.EntityFrameworkCore.BigQuery.Storage.Internal.Mapping;
169

17-
private static readonly Type _clrType = typeof(decimal);
18-
19-
public BigQueryDecimalTypeMapping(string storeType = "BIGNUMERIC(57, 28)")
10+
public class BigQueryDecimalTypeMapping : RelationalTypeMapping
11+
{
12+
public BigQueryDecimalTypeMapping(string storeType = "BIGNUMERIC(57, 28)")
2013
: base(
2114
new RelationalTypeMappingParameters(
2215
new CoreTypeMappingParameters(
2316
typeof(decimal),
24-
new DecimalToBigQueryNumericConverter(),
17+
GetConverterForStoreType(storeType),
2518
jsonValueReaderWriter: Microsoft.EntityFrameworkCore.Storage.Json.JsonDecimalReaderWriter.Instance
26-
),
19+
),
2720
storeType,
2821
StoreTypePostfix.PrecisionAndScale,
2922
System.Data.DbType.Object
3023
))
31-
{
32-
}
33-
24+
{
25+
}
3426

35-
protected BigQueryDecimalTypeMapping(RelationalTypeMappingParameters parameters)
27+
protected BigQueryDecimalTypeMapping(RelationalTypeMappingParameters parameters)
3628
: base(parameters)
37-
{
38-
}
39-
29+
{
30+
}
4031

41-
protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters parameters)
42-
=> new BigQueryDecimalTypeMapping(parameters);
32+
private static ValueConverter GetConverterForStoreType(string storeType)
33+
{
34+
return storeType.StartsWith("BIG", StringComparison.OrdinalIgnoreCase)
35+
? new DecimalToBigQueryBigNumericConverter()
36+
: new DecimalToBigQueryNumericConverter();
37+
}
4338

39+
protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters parameters)
40+
{
41+
var isBigNumeric = parameters.StoreType.StartsWith("BIG", StringComparison.OrdinalIgnoreCase);
42+
var currentIsBigNumeric = Parameters.StoreType.StartsWith("BIG", StringComparison.OrdinalIgnoreCase);
4443

45-
protected override string GenerateNonNullSqlLiteral(object value)
44+
if (isBigNumeric != currentIsBigNumeric)
4645
{
47-
string stringValue;
48-
if (value is decimal decimalValue)
49-
{
50-
stringValue = decimalValue.ToString(CultureInfo.InvariantCulture);
51-
}
52-
else if (value is Google.Cloud.BigQuery.V2.BigQueryBigNumeric bigQueryBigNumeric)
53-
{
54-
stringValue = bigQueryBigNumeric.ToString();
55-
}
56-
else if (value is Google.Cloud.BigQuery.V2.BigQueryNumeric bigQueryNumeric)
57-
{
58-
stringValue = bigQueryNumeric.ToString();
59-
}
60-
else
61-
{
62-
stringValue = value.ToString() ?? "0";
63-
}
46+
return new BigQueryDecimalTypeMapping(parameters.StoreType);
47+
}
6448

65-
string typePrefix = Parameters.StoreType.StartsWith("BIG", StringComparison.OrdinalIgnoreCase)
66-
? "BIGNUMERIC"
67-
: "NUMERIC";
49+
return new BigQueryDecimalTypeMapping(parameters);
50+
}
6851

69-
return $"{typePrefix} '{stringValue}'";
52+
protected override string GenerateNonNullSqlLiteral(object value)
53+
{
54+
string stringValue;
55+
if (value is decimal decimalValue)
56+
{
57+
stringValue = decimalValue.ToString(CultureInfo.InvariantCulture);
7058
}
71-
72-
protected override void ConfigureParameter(DbParameter parameter)
59+
else if (value is Google.Cloud.BigQuery.V2.BigQueryBigNumeric bigQueryBigNumeric)
60+
{
61+
stringValue = bigQueryBigNumeric.ToString();
62+
}
63+
else if (value is Google.Cloud.BigQuery.V2.BigQueryNumeric bigQueryNumeric)
64+
{
65+
stringValue = bigQueryNumeric.ToString();
66+
}
67+
else
7368
{
74-
base.ConfigureParameter(parameter);
69+
stringValue = value.ToString() ?? "0";
70+
}
71+
72+
string typePrefix = Parameters.StoreType.StartsWith("BIG", StringComparison.OrdinalIgnoreCase)
73+
? "BIGNUMERIC"
74+
: "NUMERIC";
75+
76+
return $"{typePrefix} '{stringValue}'";
77+
}
7578

76-
if (parameter is BigQueryParameter bigQueryParameter)
77-
{
78-
// Use BigNumeric since DecimalToBigQueryNumericConverter produces BigQueryBigNumeric objects
79-
bigQueryParameter.BigQueryDbType = Google.Cloud.BigQuery.V2.BigQueryDbType.BigNumeric;
80-
}
79+
protected override void ConfigureParameter(DbParameter parameter)
80+
{
81+
base.ConfigureParameter(parameter);
82+
83+
if (parameter is BigQueryParameter bigQueryParameter)
84+
{
85+
bigQueryParameter.BigQueryDbType = Parameters.StoreType.StartsWith("BIG", StringComparison.OrdinalIgnoreCase)
86+
? Google.Cloud.BigQuery.V2.BigQueryDbType.BigNumeric
87+
: Google.Cloud.BigQuery.V2.BigQueryDbType.Numeric;
8188
}
8289
}
8390
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Google.Cloud.BigQuery.V2;
2+
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
3+
using System.Globalization;
4+
5+
namespace Ivy.EntityFrameworkCore.BigQuery.Storage.ValueConversion.Internal;
6+
7+
/// <summary>
8+
/// Converts decimal values to BigQueryBigNumeric for BIGNUMERIC columns.
9+
/// </summary>
10+
public class DecimalToBigQueryBigNumericConverter : ValueConverter<decimal, BigQueryBigNumeric>
11+
{
12+
public DecimalToBigQueryBigNumericConverter(ConverterMappingHints? mappingHints = null)
13+
: base(
14+
v => BigQueryBigNumeric.Parse(v.ToString(CultureInfo.InvariantCulture)),
15+
v => v.ToDecimal(LossOfPrecisionHandling.Truncate),
16+
mappingHints
17+
)
18+
{
19+
}
20+
}
Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
1-
using Google.Cloud.BigQuery.V2;
1+
using Google.Cloud.BigQuery.V2;
22
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
3-
using System;
4-
using System.Collections.Generic;
53
using System.Globalization;
6-
using System.Linq;
7-
using System.Text;
8-
using System.Threading.Tasks;
94

10-
namespace Ivy.EntityFrameworkCore.BigQuery.Storage.ValueConversion.Internal
5+
namespace Ivy.EntityFrameworkCore.BigQuery.Storage.ValueConversion.Internal;
6+
7+
/// <summary>
8+
/// Converts decimal values to BigQueryNumeric for NUMERIC columns.
9+
/// </summary>
10+
public class DecimalToBigQueryNumericConverter : ValueConverter<decimal, BigQueryNumeric>
1111
{
12-
public class DecimalToBigQueryNumericConverter : ValueConverter<decimal, BigQueryBigNumeric>
12+
public DecimalToBigQueryNumericConverter(ConverterMappingHints? mappingHints = null)
13+
: base(
14+
v => BigQueryNumeric.Parse(v.ToString(CultureInfo.InvariantCulture)),
15+
v => v.ToDecimal(LossOfPrecisionHandling.Truncate),
16+
mappingHints
17+
)
1318
{
14-
public DecimalToBigQueryNumericConverter(ConverterMappingHints? mappingHints = null)
15-
: base(
16-
v => BigQueryBigNumeric.Parse(v.ToString(CultureInfo.InvariantCulture)),
17-
v => v.ToDecimal(LossOfPrecisionHandling.Truncate),
18-
mappingHints
19-
)
20-
{
21-
}
2219
}
2320
}

0 commit comments

Comments
 (0)