tsunami

log in
history

EF Core: backing fields

Luke Breuer
2017-10-12 08:53 UTC
(no tags)

ef.readthedocs.io: Backing Fields
docs.microsoft.com: Backing Fields
  • This feature is new in EF Core 1.1.
  • By convention, the following fields will be discovered as backing fields for a given property (listed in precedence order). Fields are only discovered for properties that are included in the model.

Design Meeting Notes - February 20, 2013
  • referenced from SO
  • discusses adding backing fields
using System;
using Microsoft.EntityFrameworkCore;

/*
create database Backing_Test
go
use Backing_Test
create table TestEntities (Id int identity, InputUser nvarchar(128) not null)
go
insert TestEntities (InputUser) values ('Lone Ranger')
select * from TestEntities
*/
// Install-Package Microsoft.EntityFrameworkCore.SqlServer
namespace EFCoreTest
{
    public class TestEntity
    {
        protected string _inputUser;
        public int Id { get; set; }
        public string InputUser => _inputUser;
    }

    public class BasicContext : DbContext
    {
        public DbSet<TestEntity> TestEntities { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) =>
            optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Backing_Test;Trusted_Connection=True;");
    }

    public class ExplicitBackingDbContext : BasicContext
    {
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<TestEntity>()
                .Property(e => e.InputUser)
                .HasField("_inputUser");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            const int Id = 1;

            foreach (var context in new[] { new BasicContext(), new ExplicitBackingDbContext() })
            {
                var e = context.TestEntities.Find(Id);
                Console.WriteLine($"{context.GetType().Name}\n\t{e.InputUser ?? "NULL"}");
                context.Dispose();
            }
        }
    }
}
using System;
using Microsoft.EntityFrameworkCore;

// Install-Package Microsoft.EntityFrameworkCore.InMemory
namespace EFCoreTest
{
    public class TestEntity
    {
        protected string _inputUser;
        public int Id { get; set; }
        public string InputUser => _inputUser;

        public TestEntity(string inputUser) => _inputUser = inputUser;
        private TestEntity() { }
    }

    public class BasicContext : DbContext
    {
        public DbSet<TestEntity> TestEntities { get; set; }
        public BasicContext(DbContextOptions options) : base(options) { }
    }

    public class ExplicitBackingContext : BasicContext
    {
        public ExplicitBackingContext(DbContextOptions options) : base(options) { }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<TestEntity>()
                .Property(e => e.InputUser)
                .HasField("_inputUser");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Test(o => new BasicContext(o));
            Test(o => new ExplicitBackingContext(o));
        }

        static void Test<T>(Func<DbContextOptions, T> creator) where T : BasicContext
        {
            const int Id = 1;
            var options = new DbContextOptionsBuilder()
                .UseInMemoryDatabase(databaseName: "Irrelevant")
                .Options;

            using (T context = creator(options))
            {
                context.TestEntities.Add(new TestEntity("Lone Ranger") { Id = Id });
                context.SaveChanges();
            }
            using (T context = creator(options))
            {
                var e = context.TestEntities.Find(Id);
                Console.WriteLine($"{context.GetType().Name}\n\t{e.InputUser ?? "NULL"}");
            }
        }
    }
}
Both of the above result in:
BasicContext
        NULL
ExplicitBackingContext
        Lone Ranger