1

I have a EF model where it has the following property:

public Uri? LinkedIn { get; set; }

In my IEntityTypeConfiguration.Configure I have:

builder.Property(e => e.LinkedIn).HasConversion(v => v.ToString(), v => new Uri(v));

I get a warning that the v in the v.ToString() might be null. But if I change it to:

builder.Property(e => e.LinkedIn).HasConversion(v => v?.ToString(), v => new Uri(v));

I get an error saying I can't have a null check in a lambda operator. I've tried parens, and explicit check, etc and it's unhappy with all of them.

Now can I do this? This is in EntityFramework Core but I think that's irrelevant to this question.

David Thielen
  • 28,723
  • 34
  • 119
  • 193
  • 1
    What happens if you do something like `v => v?.ToString()??string.Empty`? What's the exact error message? – Flydog57 Mar 15 '23 at 18:44

3 Answers3

2

Since the source type is nullable (Uri?), the target type should also be nullable (string?), hence the conversion should resolve to HasConversion<Uri?, string?>.

In other words, both expressions should accept nullable type argument and return nullable type result. In your case

.Property(e => e.LinkedIn)
.HasConversion(
    v => v != null ? v.ToString() : null,
    v => v != null ? new Uri(v) : null);

This eliminates the warnings in EF Core 7.0 project with NRT enabled. If you still get warnings, you probably are using older EF Core version, where not all APIs were properly NRT annotated.

Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
1

you can achieve what you need in the old fashioned way:

Instead of

v => v?.ToString()

use

v => v == null ? "" : v.ToString()

According to this site (https://shiftkeysoftware.wordpress.com/2015/09/10/you-cannot-use-a-null-propagating-operator-in-an-expression-tree-lambda/), the reason for this behavior is, that your code needs to be translated to sql and the ef core provider doesn't support the new syntax.

This seems plausible, since this can be compiled without complaining:

// no ef involved; just c# code
Func<string, object> conversion = v => v?.ToString();
Jürgen Röhr
  • 886
  • 6
  • 10
  • I was 100% I had tried that before asking here. But I tried again based on your suggestion. And it works. So I was doing something wrong when I tried that before. Anyways, thanks. – David Thielen Mar 15 '23 at 19:55
0

You can tell the compiler this value will never be null using the Null-Forgiving Operator, just add a ! after v like this

builder.Property(e => e.LinkedIn).HasConversion(v => v!.ToString(), v => new Uri(v));

Andre.Santarosa
  • 1,150
  • 1
  • 9
  • 22