Skip to content

Commit 99d0453

Browse files
committed
Value Conversions
1 parent 01cf5ab commit 99d0453

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

src/EntityFrameworkCore.SqlServer.SimpleBulks/ColumnInfor.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Microsoft.EntityFrameworkCore.Metadata;
2+
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
23
using System;
34

45
namespace EntityFrameworkCore.SqlServer.SimpleBulks;
@@ -20,4 +21,6 @@ public class ColumnInfor
2021
public bool IsPrimaryKey { get; init; }
2122

2223
public bool IsRowVersion { get; init; }
24+
25+
public ValueConverter? ValueConverter { get; set; }
2326
}

src/EntityFrameworkCore.SqlServer.SimpleBulks/Extensions/DbContextExtensions.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Microsoft.EntityFrameworkCore;
33
using Microsoft.EntityFrameworkCore.Metadata;
44
using Microsoft.EntityFrameworkCore.Storage;
5+
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
56
using System;
67
using System.Collections.Concurrent;
78
using System.Collections.Generic;
@@ -24,6 +25,7 @@ public static class DbContextExtensions
2425
private static readonly ConcurrentDictionary<CacheKey, IReadOnlyList<string>> _insertablePropertyNamesCache = [];
2526
private static readonly ConcurrentDictionary<CacheKey, IReadOnlyList<string>> _allPropertyNamesCache = [];
2627
private static readonly ConcurrentDictionary<CacheKey, IReadOnlyList<string>> _allPropertyNamesWithoutRowVersionsCache = [];
28+
private static readonly ConcurrentDictionary<CacheKey, IReadOnlyDictionary<string, ValueConverter>> _valueConvertersCache = [];
2729

2830
public static TableInfor GetTableInfor(this DbContext dbContext, Type type)
2931
{
@@ -77,7 +79,8 @@ public static IReadOnlyList<ColumnInfor> GetProperties(this DbContext dbContext,
7779
ValueGenerated = entityProp.ValueGenerated,
7880
DefaultValueSql = entityProp.GetDefaultValueSql(),
7981
IsPrimaryKey = entityProp.IsPrimaryKey(),
80-
IsRowVersion = entityProp.IsRowVersion()
82+
IsRowVersion = entityProp.IsRowVersion(),
83+
ValueConverter = entityProp.GetValueConverter(),
8184
}).ToArray();
8285
return data;
8386
});
@@ -153,6 +156,16 @@ public static IReadOnlyList<string> GetAllPropertyNamesWithoutRowVersions(this D
153156
});
154157
}
155158

159+
public static IReadOnlyDictionary<string, ValueConverter> GetValueConverters(this DbContext dbContext, Type type)
160+
{
161+
var cacheKey = new CacheKey(dbContext.GetType(), type);
162+
return _valueConvertersCache.GetOrAdd(cacheKey, (key) =>
163+
{
164+
var properties = dbContext.GetProperties(key.EntityType);
165+
return properties.Where(x => x.ValueConverter != null).ToDictionary(x => x.PropertyName, x => x.ValueConverter);
166+
});
167+
}
168+
156169
public static IDbCommand CreateTextCommand(this DbContext dbContext, string commandText, BulkOptions options = null)
157170
{
158171
return dbContext.GetSqlConnection().CreateTextCommand(dbContext.GetCurrentSqlTransaction(), commandText, options);

src/EntityFrameworkCore.SqlServer.SimpleBulks/Extensions/IListExtensions.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
12
using System;
23
using System.Collections.Generic;
34
using System.ComponentModel;
@@ -74,4 +75,24 @@ public static async Task<DataTable> ToDataTableAsync<T>(this IEnumerable<T> data
7475
return data.ToDataTable(propertyNames, addIndexNumberColumn, cancellationToken);
7576
}, cancellationToken);
7677
}
78+
79+
private static Type GetProviderClrType(PropertyDescriptor property, IReadOnlyDictionary<string, ValueConverter> valueConverters)
80+
{
81+
if (valueConverters != null && valueConverters.TryGetValue(property.Name, out var converter))
82+
{
83+
return converter.ProviderClrType;
84+
}
85+
86+
return Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
87+
}
88+
89+
private static object GetProviderValue<T>(PropertyDescriptor property, T item, IReadOnlyDictionary<string, ValueConverter> valueConverters)
90+
{
91+
if (valueConverters != null && valueConverters.TryGetValue(property.Name, out var converter))
92+
{
93+
return converter.ConvertToProvider(property.GetValue(item));
94+
}
95+
96+
return property.GetValue(item);
97+
}
7798
}

0 commit comments

Comments
 (0)