EF6 to EF Core migration cheatsheet

This is from my old notes around EF Core 3.1 timeframe in case it's useful for anyone else. It might be outdated now though.

EF6

EF Core Equivalent

DbModelBuilder

ModelBuilder

DbEntityValidationException

n/a (use Validator.TryValidateObject if you really need to validate)

db.Database.CreateIfNotExists()

db.Database.EnsureCreated()

// composite keys with attributes


[Key]

public int Field1 { get; set; }


[Key]

public int Field2 { get; set; }

modelBuilder.Entity<TEntity>()

  .HasKey(e => new { e.Field1, e.Field2 });

[Index("IX_test", Order = 2]
public int FieldA { get; set; }

[Index("IX_test", Order = 1]
public string FieldB { get; set; }

builder.Entity<TEntity>.HasIndex(e => new { e.FieldB, e.FieldA }).HasName("IX_test");

HasOptional()

HasOne() (nullability determines optionality)

HasRequired()

HasOne(...).IsRequired()

WithOptional()

WithOne() (nullability determines optionality)

WithRequired()

WithOne() (nullability determines optionality)

HasPrecision(x, y)

.HasColumnType("DECIMAL(x,y)");

WillCascadeOnDelete(false);

remove (default behavior)

WillCascadeOnDelete(true);

OnDelete(DeleteBehavior.Cascade);

HasMany().WithMany()

NOT SUPPORTED (use a mapping table to keep the mappings)

SqlFunctions.GetDate()

DateTime.Now (automatically translated in queries, and we don't care about web server/db server time differences in other scenarios as we're keeping them in sync)

SqlFunctions.DateAdd("hour", x, y)

EF.Functions.DateAddHour(x, y)

SqlFunctions.Xxx

EF.Functions.Xxx is your best bet.

SqlFunctions.TruncateTime(dateField)

dateField.Date

SqlFunctions.PatIndex

if it's just "> 0", use EF.Functions.Like(...) instead. 


You can also use "String.StartsWith()" when applicable.

SqlFunctions.DateDiff()

EF.Functions.DateDiffHour()

db.Database.ExecuteSqlCommand("SELECT NULL");

db.Database.ExecuteSqlRaw("SELECT NULL");

db.Database.ExecuteSqlCommand("SELECT * FROM params WHERE field1 = {0} AND field2 = {1}", param1, param2);

db.Database.ExecuteSqlRaw("SELECT * FROM params WHERE field1 = {0} AND field2 = {1}", param1, param2);


--or--


db.Database.ExecuteSqlInterpolated("SELECT * FROM params WHERE field1 = {param1} AND field2 = {param2}");

Database.CommandTimeout = 60;

Database.SetCommandTimeout(60);

db.Database.SqlQuery<int>("SELECT 1 FROM blabla WHERE field1 = {0} AND field2 = {1}", param1, param2);

db.Connection.Query<int>("SELECT 1 FROM blabla WHERE field1 = @param1 AND field2 = @param2", new { param1, param2 });

.GroupBy(e => e.NavPropA)

.Select(g => g.Key.NavPropB.Field1)

.GroupBy(e => e.ForeignKeyFieldA)

.Select(g => db.Table.Where(t => t.FieldA == g.Key).Select(t => t.NavPropB.Field1).Single())


or


.GroupBy(e => e.NavPropA.NavPropB.Field1)

.Select(g => g.Key.Field1)

.Select(e => e.NavPropA.Field1)

.Include(e => e.NavPropA)

.Select(e => e.NavPropA.Field1)

.Where(e => e.Field1.ToString() == EntryStatus.Blabla)


or 


.Where(e => e.Field1 == (string)EntryStatus.Blabla)


.Where(e => e.Field1 == EntryStatus.Blabla);

.GroupBy(...)

.Select(g => g.Select(..).Distinct().Count())

N/A - Only supported on EF Core 5.0+

.GroupBy(...)

.Select(g => g.Select(...).Count())

.GroupBy(...)

.Select(g => g.Count())

.OrderBy(g => g.Max(x => x.Value))

// where x.Value is a non-nullable type

.OrderBy(g => g.Max(x => (type?)x.Value)