Entity Framework Core Extensions: Getting Primary Keys and Dirty Properties

Two simple hacks: finding the primary key values:

public static IDictionary<string, object> GetKeys(this DbContext ctx, object entity)
{
if (ctx == null)
{
throw new ArgumentNullException(nameof(ctx));
}

if (entity == null)
{
throw new ArgumentNullException(nameof(entity));
}

var entry = ctx.Entry(entity);
var primaryKey = entry.Metadata.FindPrimaryKey();
var keys = primaryKey.Properties.ToDictionary(x => x.Name, x => x.PropertyInfo.GetValue(entity));

return keys;
}

This returns a dictionary because some entities may have composite primary keys.

As for getting the dirty (modified) properties’ names for an entity:

public static IEnumerable<string> GetDirtyProperties(this DbContext ctx, object entity)
{
if (ctx == null)
{
throw new ArgumentNullException(nameof(ctx));
}

if (entity == null)
{
throw new ArgumentNullException(nameof(entity));
}

var entry = ctx.Entry(entity);
var originalValues = entry.OriginalValues;
var currentValues = entry.CurrentValues;

foreach (var prop in originalValues.Properties)
{
if (object.Equals(originalValues[prop.Name], currentValues[prop.Name]) == false)
{
yield return prop.Name;
}
}
}
Picking on the last one, if we wish to reset an entity to it’s original values:
public static void Reset(this DbContext ctx, object entity)
{
if (ctx == null)
{
throw new ArgumentNullException(nameof(ctx));
}

if (entity == null)
{
throw new ArgumentNullException(nameof(entity));
}

var entry = ctx.Entry(entity);
var originalValues = entry.OriginalValues;
var currentValues = entry.CurrentValues;

foreach (var prop in originalValues.Properties)
{
currentValues[prop.Name] = originalValues[prop.Name];
}

entry.State = EntityState.Unchanged;
}

Mind you, this one will not reset collections or references, just plain properties.

Hope it helps!

This is the eight post in a series of posts about bringing the features that were present in Entity Framework pre-Core into EF Core. The others are:

  • Part 1: Introduction, Find, Getting an Entity’s Id Programmatically, Reload, Local, Evict

  • Part 2: Explicit Loading

  • Part 3: Validations

  • Part 4: Conventions

  • Part 5: Getting the SQL for a Query

  • Part 6: Lazy Loading

  • Part 7: Entity Configuration in Mapping Classes

This time I’m going to talk about the possibility to log the generated SQL to the output. In the past, we could do it by assigning a writer to DbContext.Database.Log:

ctx.Database.Log = Console.Log;
This would cause all SQL statements to be sent to the console. We can do something similar in EF Core, by leveraging the logging framework:
var loggerFactory = new LoggerFactory()
.AddDebug((categoryName, logLevel) => (logLevel == LogLevel.Information) && (categoryName == DbLoggerCategory.Database.Command.Name))
.AddConsole((categoryName, logLevel) => (logLevel == LogLevel.Information) && (categoryName == DbLoggerCategory.Database.Command.Name));

var optionsBuilder = new DbContextOptionsBuilder<MyContext>()
.UseLoggerFactory(loggerFactory)
.UseSqlServer(@"<connectionString>");

var ctx = new MyContext(optionsBuilder.Options);
We are creating a new logger factory and populating it with the console and debug providers. You will need to add the Microsoft.Extensions.Logging.Console and Microsoft.Extensions.Logging.Debug NuGet packages (you don’t need both). For each of these providers, we are filtering the output by LogLevel.Information and category DbLoggerCategory.Database.Command.Name (“Microsoft.EntityFrameworkCore.Database.Command”), which are the values used when outputting SQL.

Then, we are creating a DbContextOptionsBuilder and in it we are replacing the default logger factory with our own. We then use it to create an option which we pass to our DbContext’s constructor, or we could do the same in the OnConfiguring method.

The output will look something like this:

SELECT [p].[ProjectId], [p].[CreatedAt], [p].[CreatedBy], [p].[CustomerId], [p].[Description], [p].[End], [p].[Name], [p].[Start], [p].[UpdatedAt], [p].[UpdatedBy]
FROM [Projects] AS [p]

Hope this helps! Winking smile

 

What’s New and Changed in Entity Framework Core 2

Introduction

By now you should know that EF Core 2 was released on August 14th. It brought something new and some breaking changes too. Alas, it still does not include some of the features that used to be in pre-Core editions and are in high demand, such as lazy loading and support for group by translation. See the list here.

.NET Standard 2.0

Entity Framework Core 2 now targets .NET Standard 2.0, which was also released just now. This means that it will be useful in other scenarios, on any platform that supports it.

Improved SQL Generation

Improvements include:

  • Unneeded nested sub-queries are not created
  • Select only requested columns (projections)
  • No more creating multiple SQL queries for a single LINQ query

Owned Entities

Complex types are back, and they are now called owned entities. Remember that a difference between a complex type and an entity is that the former does not have an identity. Think, for example, of an Address class and several properties, Personal, Work, etc; all of these properties can be mapped to this class, and they will be stored in the same table as the containing entity. It looks like this:

modelBuilder
.Entity<Customer>()
.OwnsOne(c => c.PersonalAddress);

You can also put the content for these properties in another table, and you do it like this:

modelBuilder
.Entity<Customer>()
.OwnsOne(c => c.PersonalAddress)
.ToTable(“CustomerAddress”);

Of course, you can “own” multiple properties at once. Not possible to declare owned entities through attributes at this time.

Table Splitting

You can now have different classes that point to the same physical table, Entity Framework Core will not complain. These classes will probably expose different properties.

Entity State Listener

There’s a new interface that is registered by default, ILocalViewListener, that can be used to track entity changes – not materialized entities, unfortunately:

var events = ctx.GetService<ILocalViewListener>();
events.RegisterView((entry, state) =>
{
//entry contains the entity and state its current state
});

In case you are wondering, you cannot use this to cancel changes, because it is only called after the actual event took place.

Pluralization

There is a new IPluralizer interface and a dummy implementation NullPluralizer. It can be used to pluralize table names when EF is generating the database (dotnet ef database update) or entities when generating classes from it (Scaffold-DbContext). The way to use it is somewhat tricky, as we need to have a class implementing IDesignTimeServices, and this class will be discovered automatically by these tools:

public class CustomPluralizerDesignTimeServices : IDesignTimeServices
{
public void ConfigureDesignTimeServices(IServiceCollection services)
{
services.AddSingleton<IPluralizer, CustomPluralizer>();
}
}

public class CustomPluralizer : IPluralizer
{
public string Pluralize(string name)
{
return ...;
}

public string Singularize(string name)
{
return ...;
}
}

Because the tools also rely on the dependency injection framework, we are providing an alternative implementation of the IPluralizer interface through it.

DbContext Pools

Normally when a DbContext is injected somewhere by the dependency injection framework, a new instance is created every time. With this, we can have a pool of instances, 128 by default. It is a performance improvement and it is configured like this:

services.AddDbContextPool<DataContext>(options =>
{
//...
}, poolSize: 256);

Attach

The Attach method, for attaching existing entities, is now more clever: if any of the entities in the graph being attached has its key set, it will be treated as unchanged, and if not, as new.

Entity Type Configuration

We can now store entity configuration in separate classes, similar to what we used to have:

public class MyEntityTypeConfiguration : IEntityTypeConfiguration<MyEntity>
{
public void Configure(EntityTypeBuilder<MyEntity> builder)
{
//...
}
}

only these classes are not discovered automatically any more:

modelBuilder.ApplyConfiguration(new MyEntityTypeConfiguration());

Global Filters

Global filters already existed, for entities, not collections, in pre-Core EF. They are useful in essentially two scenarios:

  • For multitenant apps
  • For soft deletes

Its configuration goes like this for soft deletes:

modelBuilder
.Entity<Post>()
.HasQueryFilter(p => !p.IsDeleted);

Or, for a multi-tenant:

modelBuilder
.Entity<Blog>()
.HasQueryFilter(p => p.TenantId == this.TenantId);

It will apply filtering to any entities loaded as the result of a query (including eager loads) or from a one-to-many collection, but it will not filter a query by id, a one-to-one or many-to-one.

You can explicitly disable any existing filters by calling the IgnoreQueryFilters extension method:

ctx
.Blog
.IgnoreQueryFilters()
.ToList();

Disabling Client-Side Evaluation

You may be aware that EF Core can do client-side evaluation of methods that it does not know about, that is, cannot be translated to database calls. This happens transparently and may turn into a performance issue. Should you need to disable this, you now can by configuring the logging infrastructure to throw an exception when client evaluation occurs:

var builder = new DbContextOptionsBuilder<DataContext>()
.ConfigureWarnings(options =>
{
options.Throw(RelationalEventId.QueryClientEvaluationWarning);
options.Default(WarningBehavior.Log);
});

Like

We now have support for SQL’s LIKE function, although in the past we also supported something similar, through the String.Contains method. It goes like this:

ctx
.Posts
.Where(x => EF.Functions.Like(x.Title, “%NET%”)
.ToList();

Unfortunately, Microsoft didn’t make Like an extension method, which I think would be easier to use.

Calling Scalar Functions

Support for calling scalar functions is back too, with some minor caveats:

  • These functions need to be static and declared on the context class
  • They can only return and take as parameters scalar values

An example, first, the declaration, using the T-SQL built-in SOUNDEX function, through the [DbFunction] attribute:

[DbFunction]
public static string Soundex(string name)
{
throw new NotImplementedException();
}

Or by code:

modelBuilder.HasDbFunction(this.GetType().GetMethod(“Soundex”));

In either case you can specify both the schema or the function’s name, if it is different from the method to be used:

[DbFunction("FuncName", Schema = "dbo")]

modelBuilder.HasDbFunction(this.GetType().GetMethod("FuncName"), options =>
{
options.HasName("FuncName");
options.HasSchema("dbo");
});

And its usage:

var sounds = ctx
.MyEntity
.Select(x => x.Soundex(x.Name))
.ToList();

String Interpolation Support

Now, the FromSql and ExecuteSqlCommand methods support interpolated strings, and will happily produce parameters as needed. You do not have to worry about those nasty SQL injection attacks and performance issues due to query plan creation! It goes like this:

ctx
.Database
.ExecuteSqlCommand($"UPDATE Record SET Value = {value} WHERE Id = {id}");

Explicitly Compiled Queries

Entity Framework Core included query caching since version 1, but there is still some overhead associated with calculating the key from the query and getting it from the cache. Therefore, version 2 introduced a capability that existed in LINQ to SQL and Entity Framework pre-Core: explicit query compilation and execution. By this, we are able to pre-compile a query and use it in whatever context we want (of a compatible type, of course). We can even eagerly fetch associated collections or entities:

static readonly Func<MyEntityContext, int, IEnumerable<MyEntity>> 
CompiledQuery = EF.CompileQuery<MyEntityContext, int, MyEntity>((ctx, id) =>
ctx.MyEntities.Where(x => x.Id == id).Include(x => x.Others).OrderBy(x => x.Name));

As you can see, it returns a delegate that we can invoke passing it the proper parameters – in this example, a context and a parameter, but you can have up to 8 parameters, of different types:

var results = CompiledQuery(ctx, 100).ToList();

Breaking Changes

The IDbContextFacfory<T> interface was replaced by IDesignTimeDbContextFactory<T>. The signature of the CreateDbContext method changed also:

public class DummyContextFactory : IDesignTimeDbContextFactory<DummyContext>
{
    public DummyContext CreateDbContext(string[] args)
    {
        var builder = new DbContextOptionsBuilder<DummyContext>();
        builder.UseSqlServer("…");
        return new DummyContext(builder.Options);
    }
}

UseInMemoryDatabase now needs a name:

optionsBuilder.UseInMemoryDatabase("MyDatabase")

Package Microsoft.EntityFrameworkCore.SqlServer.Design is deprecated in favor of Microsoft.EntityFrameworkCore.Design (now provider-agnostic).

Only 2.0 providers will work, so any existing providers that target EF Core 1.x will need to be rewritten.

Logging event IDs have changed from the previous version and they are now identical to those used by corresponding ILogger messages. The logger categories now come from subclasses of DbLoggerCategory, such as DbLoggerCategory.Database.Command, DbLoggerCategory.Migrations, DbLoggerCategory.Infrastructure, etc, all of which offer a Name property.

What’s Still Not Here

Still missing are (not a complete list, mind you):

You can find a more thorough list here: https://weblogs.asp.net/ricardoperes/missing-features-in-entity-framework-core.

Conclusion

Still a long way to go; especially, GroupBy translation, many to many and lazy loading seems to be taking forever, both are scheduled for the next version (2.1) though. Non-relational providers are also nowhere to be seen. This new version has interesting new stuff and Microsoft seems to be going in the right direction, but it strikes me as odd that such high demand features are still absent. Let’s see how things evolve.

References

https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-entity-framework-core-2-0

https://docs.microsoft.com/en-us/ef/core/what-is-new

https://github.com/aspnet/EntityFrameworkCore/wiki/Roadmap

https://github.com/aspnet/EntityFrameworkCore/issues?q=is%3Aopen+is%3Aissue+milestone%3A2.0.0

https://weblogs.asp.net/ricardoperes/missing-features-in-entity-framework-core

Implementing Missing Features in Entity Framework Core – Part 7: Entity Configuration in Mapping Classes

This is the seventh post in a series of posts about bringing the features that were present in Entity Framework pre-Core into EF Core. The others are:

  • Part 1: Introduction, Find, Getting an Entity’s Id Programmatically, Reload, Local, Evict

  • Part 2: Explicit Loading

  • Part 3: Validations

  • Part 4: Conventions

  • Part 5: Getting the SQL for a Query

  • Part 6: Lazy Loading

This time I’m going to cover automatic entity configuration in mapping classes, that is, outside of the DbContext.OnModelCreating method. If you remember, Entity Framework Code First supported having classes inheriting from EntityTypeConfiguration in the same assembly as the context, and these classes would be loaded automatically. This made it much simpler to add new mapping classes to a project without touching the context.

This functionality hasn’t been ported to Entity Framework Core yet, but it is being developed for the next version, and is tracked by ticket 2805. My implementation finds mapping classes in the same assembly as the context automatically, or it can load configuration explicitly from a mapping class. Here is my contract for the mapping class:

public interface IEntityTypeConfiguration<T> where T : class
{
void Configure(EntityTypeBuilder<T> entityTypeBuilder);
}

As you can see, this needs to be implemented in a concrete generic class and bound to a specific entity type.

The actual implementation goes like this:

public static class EntityTypeConfigurationExtensions
{
private static readonly MethodInfo entityMethod = typeof(ModelBuilder).GetTypeInfo().GetMethods().Single(x => (x.Name == "Entity") && (x.IsGenericMethod == true) && (x.GetParameters().Length == 0));

private static Type FindEntityType(Type type)
{
var interfaceType = type.GetInterfaces().First(x => (x.GetTypeInfo().IsGenericType == true) && (x.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>)));
return interfaceType.GetGenericArguments().First();
}

private static readonly Dictionary<Assembly, IEnumerable<Type>> typesPerAssembly = new Dictionary<Assembly, IEnumerable<Type>>();

public static ModelBuilder ApplyConfiguration<T>(this ModelBuilder modelBuilder, IEntityTypeConfiguration<T> configuration) where T : class
{
var entityType = FindEntityType(configuration.GetType());

dynamic entityTypeBuilder = entityMethod
.MakeGenericMethod(entityType)
.Invoke(modelBuilder, new object[0]);

configuration.Configure(entityTypeBuilder);

return modelBuilder;
}

public static ModelBuilder UseEntityTypeConfiguration(this ModelBuilder modelBuilder)
{
IEnumerable<Type> configurationTypes;
var asm = Assembly.GetEntryAssembly();

if (typesPerAssembly.TryGetValue(asm, out configurationTypes) == false)
{
typesPerAssembly[asm] = configurationTypes = asm
.GetExportedTypes()
.Where(x => (x.GetTypeInfo().IsClass == true) && (x.GetTypeInfo().IsAbstract == false) && (x.GetInterfaces().Any(y => (y.GetTypeInfo().IsGenericType == true) && (y.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>)))));
}

var configurations = configurationTypes.Select(x => Activator.CreateInstance(x));

foreach (dynamic configuration in configurations)
{
ApplyConfiguration(modelBuilder, configuration);
}

return modelBuilder;
}
}

You can see that it uses some dynamic magic to make things simpler, otherwise we’d need to have even more reflection. Dynamics take care of these things quite nicely.

The code essentially looks at the entry assembly and finds all non-abstract public types that implement IEntityTypeConfiguration<T>. For each of those, it creates an instance, extracts the template argument and creates an EntityTypeBuilder<T> from calling the Entity<T> method of the ModelBuilder class and calls the IEntityTypeConfiguration<T>.Configure method of the instantiated mapping class passing it the EntityTypeBuilder<T> which allows it to supply mapping configuration for the mapped entity (T).

We need to explicitly call this extension inside DbContext.OnModelCreating:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.UseEntityTypeConfiguration();
base.OnModelCreating(modelBuilder);
}

And it takes care of everything for us. Or, if we want to load a single mapping class explicitly, we can also do so:

modelBuilder.UseEntityTypeConfiguration<MyEntityTypeConfiguration>();

Finally, a simple mapping class might be:

public class MyEntityTypeConfiguration : IEntityTypeConfiguration<MyEntity>
{
public void Configure(EntityTypeBuilder<MyEntity> entityTypeBuilder)
{
entityTypeBuilder.ToTable("MyEntity");
entityTypeBuilder.Property(x => x.MyEntityId).HasColumnName("Id");
}
}

In case you’re interested, this feature is similar to the one being implemented for .NET Core, except that it doesn’t find mapping classes automatically. The IEntityTypeConfiguration<T> interface is exactly the same.

What’s New in Entity Framework Core 1.1

Introduction

Entity Framework Core 1.1 was released last November. With it, besides some bug fxes and semi-transparent improvements, came along a few goodies. If you read my previous post on features missing in Entity Framework Core 1.0, you’ll be please to know that a few have been addressed.

New API Methods

The Find method, for returning an entity from its primary key, is back (I had provided a workaround here):

var e1 = ctx.DbSet<MyEntity>().Find(1);

New is GetDatabaseValues, which goes to the database and fetches the current values for the current entity and primary key:

var dbProperties = ctx.Entry<MyEntity>(e).GetDatabaseValues();

Reload and Explicit Load

It is now again possible to reload an entity, causing it to be re-hydrated with the current values from the database, through the Reload method (also available as a workaround here):

ctx.Entry<MyEntity>(e).Reload();

And it is also possible to force load a not-loaded collection ():

ctx.Entry<MyEntity>(e).Collection(x => x.MyColl).Load();

As well as entity references (one-to-one, many-to-one):

ctx.Entry<MyEntity>(e).Reference(x => x.MyRef).Load();

Connection Resiliency

Connection resiliency made it way to version 1.1 as well:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer("my connection string", opt => opt.EnableRetryOnFailure());

base.OnConfiguring(optionsBuilder);
}

The EnableRetryOnFailure method is just a wrapper around ExecutionStrategy passing it SqlServerRetryingExecutionStrategy:

optionsBuilder
.ExecutionStrategy(x => new MyExecutionStrategy(x));

This one allows you to provide your own strategy for retries, by implementing IExecutionStrategy.

Configurable Change Tracking

Now, this is something that could have been really cool, but, as it is now, I find it somewhat crippled… you can now tell Entity Framework Core how should it find out if an entity has changed – the common change tracker functionality. But, the only supported techniques are the built-in (default, based on snapshots) or the use of INotifyPropertyChanged/INotifyCollectionChanged. This is not really that extensible, as you only have these two options. Here is how you configure it:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>()
.HasChangeTrackingStrategy(ChangeTrackingStrategy.ChangedNotifications);

base.OnModelCreating(modelBuilder);
}

If you want to use this approach, your entity must implement INotifyPropertyChanged and all of its collections must implement INotifyCollectionChanged. If any of the properties or collections in it changes, you must raise the PropertyChanged or CollectionChanged events, otherwise EF will not know that it is modified.

This can be set as the default for all entities, by the way:

modelBuilder
.HasChangeTrackingStrategy(ChangeTrackingStrategy.ChangedNotifications);

Using Fields

A most welcome addition, that was never previously available, is mapping to fields! This better supports a pure Domain Driven Design approach. It needs to be configured using code mapping:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<MyEntity>()
.Property(b => b.MyProp)
.HasField("_myField");

base.OnModelCreating(modelBuilder);
}

IEnumerable Collections

Another handy improvement is the ability to map collections declared as IEnumerable<T>, whereas in the past this was only possible for ICollection<T> (and derived classes, of course). The configuration is the same:

modelBuilder
.Entity<MyEntity>()
.HasMany(x => x.Children);

Of course, the concrete collection class must itself implement ICollection<T>, otherwise Entity Framework would have no way to populate it:

public class MyEntity
{
public IEnumerable<MyChild> Children { get; } = new HashSet<MyChild>();
}

Support for SQL Server In Memory Tables

In case you are using Hekaton, you can now tell Entity Framework that your entity is persisted as a memory-optimized table:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>()
.ForSqlServerIsMemoryOptimized();

base.OnModelCreating(modelBuilder);
}

Switching Services

Last, but not least, EF Core 1.1 makes it much easier to replace one of the services that EF uses internally:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.ReplaceService<IEntityStateListener, CustomEntityStateListener>();

base.OnConfiguring(optionsBuilder);
}

Conclusion

It’s nice to see things progressing, but there’s still a long way to go. In particular, as I said in my post about the missing features, there are quite a few features that still didn’t make it. In particular, I still miss:

  • Group By translation
  • Lazy loading
  • Date/Time operations
  • Support for custom SQL functions
  • Many-to-many relations
  • Command and query interception

We just have to wait for the next priorities of the team.

Entity Framework Core Cookbook – Second Edition

Some of you may be aware that my new book for Packt Publishing is out! It is titled Entity Framework Core Cookbook – Second Edition because it was meant to be the second edition of Entity Framework 4.1: Expert’s Cookbook. In fact, it is mostly a full rewrite.

It is organized in chapters:

Chapter 1: Improving Entity Framework in the Real World

Chapter 2: Mapping Entities

Chapter 3: Validation and Changes

Chapter 4: Transactions and Concurrency Control

Chapter 5: Querying

Chapter 6: Advanced Scenarios

Chapter 7: Performance and Scalability

Appendix: Pitfalls

When I started writing it, .NET Core was still in early RC1. Things changed a lot from RC1 to RC2 and then again to RTM, so I had to revisit all chapters in the end. It was a pity that EF Core 1.1 was released shortly after the book was closed, because I could have talked about it too. Also, there are things that I could have covered, like extending Entity Framework Core, but there were so many of them! Smile Maybe in a future time!

Those of you who are interested can get a copy from the Pack Publishing site or from other sellers, either as an e-book or in hardcopy.

I want to thank everyone at Packt Publishing, namely Chaitanya Nair, Merint Mathew and Siddhi Chavan for their professionalism and support!

What’s New in .NET Core 1.1

.NET Core 1.1 – including ASP.NET Core and Entity Framework Core – was just released at the time of the Connect(); event. With it came some interesting features and improvements.

Before you start using version 1.1 you need to make sure you install the .NET Core 1.1 SDK from https://www.microsoft.com/net/download/core. If you don’t, some stuff will not work properly.

Here are some highlights.

ASP.NET Core

In version 1.1 you can now treat View Components like Tag Helpers! Not sure why they did this, but I guess it’s OK.

You new have URL rewriting middleware that can consume the same configuration file as the IIS URL Rewrite Module.

Also new is Caching middleware, bringing what was Output Cache in ASP.NET Web Forms to Core Land.

GZip compression is also starring as a middleware component.

Middleware components can now be applied as global attributes. Seems interesting, but I don’t know how this works, because we can’t specify the ordering.

Next big thing is WebListener. It’s another HTTP server, but this time tuned for Windows. Because it this, it supports Windows authentication, port sharing, HTTPS with Server Name Indication (SNI), HTTP/2 over TLS (on Windows 10), direct file transmission, and response caching WebSockets (on Windows 8 or higher).

Temp data can now be stored in a cookie, as with MVC pre-Core.

You can now log to Azure App Service and you can also get configuration information from Azure Key Vault. Still on Azure, you can make use of Redis and Azure Storage Data Protection.

Finally, something that was also previously available is view precompilation. Now you can build your views at compile time and get all errors ahead of time.

Not all is here, though: for example, mobile views are still not available.

More on https://blogs.msdn.microsoft.com/webdev/2016/11/16/announcing-asp-net-core-1-1 and https://github.com/aspnet/home/releases/1.1.0.

Entity Framework Core

The Find method is back, allowing us to load entities by their primary keys. As a side note, I have published a workaround for this for the initial version of EF Core 1.0. Same for Reload, GetModifiedProperties and GetDatabaseValues.

Explicit loading for references and collections is also here.

Connection resiliency, aka, the ability to retry a connection, also made its move to version 1.1, similar to what it was in pre-Core.

Totally new is the support for SQL Server’s Memory Optimized Tables (Hekaton).

Now we can map to fields, not just properties! This was an often requested feature, which helps follow a Domain Driven Design approach.

Also new is the capacity to change a specific service implementation without changing the whole service provider at startup.

There are more API changes and apparently LINQ translation has improved substantially. Time will tell!

A lot is still missing from pre-Core, see some of it here.

More info here: https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-entity-framework-core-1-1 and here: https://github.com/aspnet/EntityFramework/releases/tag/rel%2F1.1.0.

.NET Core

First of all, .NET Core 1.1 can now be installed in more Linux distributions than before and also in MacOS 10 and in Windows Server 2016.

The dotnet CLI has a new template for .NET Core projects.

.NET Core 1.1 supports .NET Standard 1.6.

Lots of performance improvements, bug fixes and imported APIs from .NET full.

Read more about it here: https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-net-core-1-1/ and here: https://github.com/dotnet/core/tree/master/release-notes/1.1.

Entity Framework Pitfalls: Skip/Take Position Matters

In LINQ, you normally do paging through the Skip and Take operators. These are the LINQ counterparts to whatever the relational database uses for pagination – ROW_NUMBER(), LIMIT…OFFSET, TOP, ROWNUM, etc.

There are some gotchas to it:

  • When you do paging, Entity Framework demands that you add ordering to your query. This makes sense as without an explicit ORDER BY clause, search results may come in an unexpected order;
  • Skip and Take yield different results if added to different places in the LINQ expression.

Consider these two LINQ queries:

ctx
.MyEntities
.Where(x => x.Name == "")
.OrderBy(x => x.Id)
.Skip(10)
.Take(5)
.ToList();

And:

ctx
.MyEntities
.OrderBy(x => x.Id)
.Skip(10)
.Take(5)
.Where(x => x.Name == "")
.ToList();

The first one will produce this SQL:

SELECT TOP (5)
[Filter1].[Id] AS [Id],
[Filter1].[Name] AS [Name],
[Filter1].[Date] AS [Date]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].
[Date] AS [Date], row_number() OVER (ORDER BY [Extent1].[Id] ASC) AS [row_number
]
FROM [dbo].[MyEntities] AS [Extent1]
WHERE N'' = [Extent1].[Name]
) AS [Filter1]
WHERE [Filter1].[row_number] > 10
ORDER BY [Filter1].[Id] ASC

Whereas the second will produce this one:

SELECT
[Limit1].[Id] AS [Id],
[Limit1].[Name] AS [Name],
[Limit1].[Date] AS [Date]
FROM ( SELECT TOP (5) [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].[Date] AS [Date]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].[Date] AS [Date], row_number() OVER (ORDER BY [Extent1].[Id] ASC) AS [row_number]
FROM [dbo].[MyEntities] AS [Extent1]
) AS [Extent1]
WHERE [Extent1].[row_number] > 10
ORDER BY [Extent1].[Id] ASC
) AS [Limit1]
WHERE N'' = [Limit1].[Name]
ORDER BY [Limit1].[Id] ASC

Basically, the TOP(5) expression is placed in the wrong place. So, in LINQ, it’s not just the presence of a Skip and Take operator, it’s where you place it that matters!

Entity Framework Pitfalls: Null Semantics

Imagine you have a simple class:

public class MyEntity
{
public int Id { get; set; }
public string Name { get; set; }
}

You may want to query it:

string name = ...;

var entities = ctx
.MyEntities
.Where(x => x.Name == name)
.ToList();

Entity Framework generates a query such as this:

SELECT [Extent1].[Id] AS Id, [Extent1].[Name] AS Name
FROM [dbo].[MyEntities] AS [Extent1]
WHERE ([Extent1].[Name] = @p__linq__0)
OR (([Extent1].[Name] IS NULL) AND (@p__linq__0 IS NULL))

Meaning: return all records from the MyEntities table if

  1. The Name column is identical to the name variable or
  2. Both the Name column and the name variable are NULL

Seems excessively complex, doesn’t it? Well, this is to account for the case where the name parameter is null. In  that case, a simple COLUMN = VALUE comparison won’t work, because in SQL, NULL = NULL returns FALSE! The syntax for comparing with NULL is COLUMN IS NULL. By generating this kind of query, Entity Framework is playing safe. Mind you, this only happens if you do not use the literal null, if you do, Entity Framework is smart enough to generate a simpler query:

var entities = ctx
.MyEntities
.Where(x => x.Name == null)
.ToList();

Results in:

SELECT [Extent1].[Id] AS Id, [Extent1].[Name] AS Name
FROM [dbo].[MyEntities] AS [Extent1]
WHERE ([Extent1].[Name] IS NULL)

However, there is a configuration setting, UseDatabaseNullSemantics (the opposite of the old UseCSharpNullComparisonBehavior of ObjectContext), that can be used to control this behavior. If set to true (the opposite of the default):

ctx.Configuration.UseDatabaseNullSemantics = true;

It generates all SQL queries as the unsafe version:

SELECT [Extent1].[Id] AS Id, [Extent1].[Name] AS Name
FROM [dbo].[MyEntities] AS [Extent1]
WHERE ([Extent1].[Name] = @p__linq__0)

The result is, even if you have a record whose Name column is NULL, it won’t be returned: remember that in SQL, by default, NULL <> NULL!

Therefore, if you are not 100% sure that the parameter that you will be using in the LINQ query will never be null, do not mess with UseDatabaseNullSemantics even if it generates somewhat poorer SQL.

Of course, if you are using SQL Server, you can set ANSI_NULLS to OFF, and the problem goes away; in that case, NULL = NULL.

Entity Framework Pitfalls: Queries Over Navigation Properties When There Are Foreign Key Properties Are Ignored

Long title, I know! Smile

Another one for Entity Framework Code First. The problem is: imagine you have an entity with a relation to another entity (one-to-one, many-to-one) where you have both the navigation property and the foreign key property:

public class Source
{
public int Id { get; set; }

[ForeignKey("TargetId")]
public virtual Target Target { get; set; }

public int? TargetId { get; set; }
}

public class Target
{
public int Id { get; set; }
public virtual ICollection<Source> Sources { get; set; }
}

You may want to query all Sources that have a Target set:

var sourcesWithTarget = ctx
.Sources
.Where(source => source.Target != null)
.ToList();

However, you will get this SQL instead:

SELECT [Extent1].[Id] AS [Id], [Extent1].[TargetId] AS [TargetId], 
FROM [dbo].[Source] AS [Extent1]

See? No WHERE clause!

If, instead, we query on the foreign key property:

var sourcesWithTarget = ctx
.Sources
.Where(source => source.TargetId != 0)
.ToList();

Then we get what we want:

SELECT [Extent1].[Id] AS [Id], [Extent1].[TargetId] AS [TargetId], 
FROM [dbo].[Source] AS [Extent1]
WHERE 0 <> [Extent1].[TargetId]

Weird, huh?

Stay tuned for more!