-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Need discussion of Value Comparers #1986
Need discussion of Value Comparers #1986
Comments
|
Oops. That was for converters. Agree we need docs here. |
Also shouldn't there be a default comparer for each primitive type? We have a custom string -> string converter but we still want a string comparer at the end of the day. Edit: To add, the framework should realize this and use those default comparers instead of raising a warning. |
@SidShetye There is. EF does use the default. But the default may not be correct. |
Is this the same as #1680? That doesn't seem to be linked to this page, though. |
See also #1680. Make sure this relates to collection conversions. |
@ajcvickers till the documentation comes up, is this the correct approach for ValueComparers to avoid warnings with custom converters? string
and byte[]
where |
@SidShetye Looks like you are trying to configure compares for the database type. It's the type in your model (the type that is being converted to byte[] or string) that needs to be compared. |
@ajcvickers We're transforming the values/contents, not the type itself. So Thoughts? |
@SidShetye That sounds like it could be a bug. Please post a small, runnable project that reproduces this so we can investigate. |
Still need to update the fwlink. |
I am hunting the internet for a good explanation of using the ValueConverter in my EF Core Db Context. Following is a snippet from my context. Is this snippet supposed to convert UTC from the database in to Local, and convert Local to UTC when SaveChanges() to the database? protected override void OnModelCreating(ModelBuilder modelBuilder)
{
ValueConverter<DateTime, DateTime> dateTimeConverter = new ValueConverter<DateTime, DateTime>(
v => v.ToLocalTime(),
v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
ValueConverter<DateTime?, DateTime?> nullableDateTimeConverter = new ValueConverter<DateTime?, DateTime?>(
v => v.HasValue ? v.Value.ToLocalTime() : v,
v => v.HasValue ? DateTime.SpecifyKind(v.Value, DateTimeKind.Utc) : v);
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
if (entityType.IsKeyless)
{
continue;
}
foreach (var property in entityType.GetProperties())
{
if (property.ClrType == typeof(DateTime))
{
property.SetValueConverter(dateTimeConverter);
property.SetValueComparer(new ValueComparer<DateTime>(
(l, r) => l == r,
v => StringComparer.Ordinal.GetHashCode(v),
v => v)
);
}
else if (property.ClrType == typeof(DateTime?))
{
property.SetValueConverter(nullableDateTimeConverter);
property.SetValueComparer(new ValueComparer<DateTime?>(
(l, r) => l == r,
v => StringComparer.Ordinal.GetHashCode(v),
v => v)
);
}
}
} |
@JimInNC We have docs with many examples and sample code that can be downloaded from GitHub. |
Yeah, I figured it out. The following code allows me to manually set and
store a date as UTC. When I read the date via the model, it comes back to
me as local time.
I wish there was a way for me NOT to have to manually set the time as UTC.
I wish the model would automatically convert it back to UTC when I save.
Anyway, that is what I wanted. The article you referenced, I'm sure it
explains this fully. But, I could not piece it together via that article.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
ValueConverter<DateTime, DateTime> dateTimeConverter = new
ValueConverter<DateTime, DateTime>(
v => v.ToUniversalTime(),
v => DateTime.SpecifyKind(v, DateTimeKind.Local));
ValueConverter<DateTime?, DateTime?> nullableDateTimeConverter = new
ValueConverter<DateTime?, DateTime?>(
v => v.HasValue ? v.Value.ToUniversalTime() : v,
v => v.HasValue ? DateTime.SpecifyKind(v.Value, DateTimeKind.Local) : v);
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
if (entityType.IsKeyless)
{
continue;
}
foreach (var property in entityType.GetProperties())
{
if (property.ClrType == typeof(DateTime))
{
property.SetValueConverter(dateTimeConverter);
property.SetValueComparer(new ValueComparer<DateTime>(
(l, r) => l == r,
v => StringComparer.Ordinal.GetHashCode(v),
v => v)
);
}
else if (property.ClrType == typeof(DateTime?))
{
property.SetValueConverter(nullableDateTimeConverter);
property.SetValueComparer(new ValueComparer<DateTime?>(
(l, r) => l == r,
v => StringComparer.Ordinal.GetHashCode(v),
v => v)
);
}
}
}
…On Thu, Apr 8, 2021 at 2:27 PM Arthur Vickers ***@***.***> wrote:
@JimInNC <https://github.com/JimInNC> We have docs with many examples
<https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions?tabs=data-annotations>
and sample code that can be downloaded from GitHub.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1986 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AQCOD63U3JHF3TDVZ666DRDTHXYSBANCNFSM4J2C7RKA>
.
|
So, I got this surprisingly helpful warning message, telling me that my POCO property has a value converter but no value comparer. I had followed the guidance on this page and declared a value converter, but it took a lot of digging to come up with this SO answer that showed how to declare and wire up a value comparer.
The SO answer includes a bunch of undocumented magic, in particular
propertyBuilder.Metadata.SetValueConverter
andpropertyBuilder.Metadata.SetValueComparer
.Since creation of a value converter apparently implies the necessity of creating a value comparer, please discuss this subject in this article.
Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
The text was updated successfully, but these errors were encountered: