Created
November 28, 2019 15:03
-
-
Save jakubfijalkowski/0fb68e79693f97fa19cd2002dfd67fec to your computer and use it in GitHub Desktop.
In EFCore3 custom ValueConverters don't force client-side evaluation!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using Microsoft.EntityFrameworkCore; | |
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; | |
using Microsoft.Extensions.DependencyInjection; | |
using Microsoft.Extensions.Hosting; | |
namespace EFCore.Conversions | |
{ | |
public readonly struct StrongId : IEquatable<StrongId> | |
{ | |
public Guid RawValue { get; } | |
public StrongId(Guid rawValue) | |
{ | |
RawValue = rawValue; | |
} | |
public bool Equals(StrongId other) => RawValue == other.RawValue; | |
public override bool Equals(object? obj) => obj is StrongId d && Equals(d); | |
public override int GetHashCode() => RawValue.GetHashCode(); | |
public override string ToString() => RawValue.ToString("N"); | |
public static bool operator ==(StrongId left, StrongId right) => left.RawValue == right.RawValue; | |
public static bool operator !=(StrongId left, StrongId right) => left.RawValue != right.RawValue; | |
public static explicit operator Guid(StrongId d) => d.RawValue; | |
public static explicit operator StrongId(Guid d) => new StrongId(d); | |
} | |
class Program : IHostedService | |
{ | |
static async Task Main(string[] args) | |
{ | |
await Host.CreateDefaultBuilder(args) | |
.ConfigureServices((hostContext, services) => | |
{ | |
services.AddDbContext<CoreContext>(cfg => | |
cfg.UseSqlServer("Server=localhost,1433;User Id=sa;Password=yourStrong(!)Password;Database=App")); | |
services.AddTransient<IHostedService, Program>(); | |
}) | |
.RunConsoleAsync(); | |
} | |
private readonly CoreContext dbContext; | |
public Program(CoreContext dbContext) | |
{ | |
this.dbContext = dbContext; | |
} | |
public async Task StartAsync(CancellationToken cancellationToken) | |
{ | |
await dbContext.Database.EnsureCreatedAsync(); | |
var g = Guid.NewGuid(); | |
await dbContext.Entities | |
.Where(d => d.Id == new StrongId(g)) | |
.ToListAsync(); | |
} | |
public Task StopAsync(CancellationToken cancellationToken) | |
{ | |
return dbContext.Database.EnsureDeletedAsync(); | |
} | |
} | |
public class Entity | |
{ | |
public StrongId Id { get; set; } | |
} | |
public class CoreContext : DbContext | |
{ | |
public DbSet<Entity> Entities => Set<Entity>(); | |
public CoreContext(DbContextOptions<CoreContext> options) | |
: base(options) | |
{ } | |
protected override void OnModelCreating(ModelBuilder modelBuilder) | |
{ | |
modelBuilder.Entity<Entity>(b => | |
{ | |
b.HasKey(e => e.Id); | |
b.Property(e => e.Id) | |
.ValueGeneratedNever() | |
.HasConversion(new StrongIdConverter()); | |
// Or: | |
// .HasConversion( | |
// e => e.RawValue, | |
// e => new StrongId(e)); | |
}); | |
} | |
public class StrongIdConverter : ValueConverter<StrongId, Guid> | |
{ | |
public StrongIdConverter() | |
: base( | |
e => e.RawValue, | |
e => new StrongId(e), | |
null) | |
{ } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment