static void

Entity Framework Code First Mapping

Optimistic Concurrency

EF CF follows SQL Server's confused naming (timestamp/rowversion)- the attribute is [Timestamp] and the fluent config marker is IsRowVersion()

[Timestamp]
public byte[] RowVersion { get; set; }

Property(m => m.RowVersion).IsRowVersion();

For other non=primary key properties to be involved in optimistic concurrency, add [ConcurrencyCheck] or .IsConcurrencyToken()

[ConcurrencyCheck]
public string LoginName { get; set; }

Property(m => m.LoginName).IsConcurrencyToken();

Value Objects (aka Complex Types aka Components)

Value objects in DDD are objects defined by their attributes, not by identity (like Entities). The canonical example is a Person entity which has an Address value type. On the database side of an ORM, the value properties simply live inside the entity table (People table has [Address_AddressLine1] column). In NHibernate these are called Components, in EF they are Complex Types.
If you follow conventions, it should just work. They must have no key ("Id" property) or be in a collection (ICollection<Address>), and you can't have nested complex types. If you have anything that looks like an "Id" property, mark the class with [ComplexType]. In code:

//must be AFTER model.Configurations.Add
modelBuilder.ComplexType<Address>()
    .Property(p => p.AddressLine1).HasColumnName("Address1");

Or create a mapping class:

public class AddressConfiguration : ComplexTypeConfiguration<Address>

Instantiate the value object in the parent entity's constructor.

Ignoring classes and properties

Related classes will be mapped even if they are not in a DbSet. So mark them as [NotMapped] or in code:

modelBuilder.Ignore<CalculatedClass>();

Unlike NHibernate, all properties with public getters and a public/internal/private setter are mapped automatically. Properties with getter but no setter are automatically ignored. Private setters are allowed, and the property will be mapped, so you may need to mark them to be ignored.

For properties (such as calculated properties), use the same markers i.e.[NotMapped] and

Ignore(m => m.CalculatedProperty);

NB: you can map internal properties (if they are in the same assembly, or with InternalsVisibleTo) if you explicitly configure them in the fluent API. You can also map protected and private properties if the mapping configuration is nested inside the entity.
Setters can be private if the getter is public, but this doesn't work in MediumTrust (eg Azure hosting).

Indexes

Since EF 6.1 (2014), you can add an [System.ComponentModel.DataAnnotations.Schema.Index(IsUnique = true)] to properties (if your entities project references EF).

Fluent configuration in DbContext.OnModelCreating is available, but really ugly.

modelBuilder.Entity<MyEntity>().Property(x => x.Name)
    .HasColumnAnnotation(IndexAnnotation.AnnotationName,
        new IndexAnnotation(new IndexAttribute { IsUnique = true }));

Both these create the migration instruction, or you can add it manually:

CreateIndex("dbo.MyEntities", "Name", unique: true);

Table Per Hierarchy (TPH)

In the database, this is a single table with a discriminator column. This is the default inheritance model in CF if it finds class inheritance; it creates a column [Discriminator] nvarchar(128) NOT NULL. The type name is the value.

By default, EF Code First turns inherited classes into TPH. If you specify table names for the derived classes you get TPT (see below).

You can customize the discriminator column in the fluent API. For each derived class:

public class CatConfiguration : EntityTypeConfiguration<Cat>
{
    public CatConfiguration()
    {
        Map(m => m.Requires("CarnivoreType").HasValue("Cat"));
    }
}

If the base class is not abstract, it can also have the .Requires(name).HasValue(object). The value doesn't have to be a string... EF will infer the database type (int or bool).

There is a bug in EF 4.3 (fixed in EF 5). Don't map the derived classes in the base class with chaining... you'll get an exception "Map was called more than once for type 'Cat' and at least one of the calls didn't specify the target table name."

From EF 5, the following chaining is also fine:

Map(m =>
        {
            m.ToTable("Carnivores");
            m.Requires("CarnivoreType").HasValue("Generic");
        })
.Map<Cat>(m => m.Requires("CarnivoreType").HasValue("Cat"))
.Map<Dog>(m => m.Requires("CarnivoreType").HasValue("Dog"));

Type per Type (TPT)

In the database, this is a base table (= the base class) with separate tables for each derived class and a foreign key between them.
You can map the derived table classes to specific names with .ToTable("x") or more explicitly from the base class:

There's a bug in EF 4.3 (possibly the same as in TPH), where the chaining in the base class doesn't work. The error is "The type 'Cat' has already been mapped to table 'Cats'. Specify all mapping aspects of a table in a single Map call."

public class CarnivoreConfiguration : EntityTypeConfiguration<Carnivore>
{
    public CarnivoreConfiguration()
    {
        //the base table
        Map(m => m.ToTable("Carnivores"))
            //the derived tables
            //EF 4.3 InvalidOperationException:
            //  The type 'Cat' has already been mapped to table 'Cats'.
            //  Specify all mapping aspects of a table in a single Map call.
            .Map<Cat>(m => m.ToTable("Cats"))
            .Map<Dog>(m => m.ToTable("Dogs"));
    }
}

The less explicit way (workaround for EF 4.3):

modelBuilder.Entity<Carnivore>().ToTable("Carnivores");
modelBuilder.Entity<Cat>().ToTable("Cat");
modelBuilder.Entity<Dog>().ToTable("Dog");

Table per Concrete Class (TPC)

In the database, this is a table per derived class, with no common base table. In the fluent API you use MapInheritedProperties - but you will have to add explicit mappings for navigation properties.

modelBuilder.Entity<Cat>()
    .Map(m =>
            {
                m.ToTable("Cats");
                m.MapInheritedProperties();
            });
modelBuilder.Entity<Dog>()
    .Map(m =>
            {
                m.ToTable("Dogs");
                m.MapInheritedProperties();
            });