[Entity Framework] Code First – Fluent API Classes

The Fluent API functionality is exposed by Entity Framework class library (“EntityFramework.dll“). The classes are located in the following 3 namespaces:

  • System.Data.Entity.ModelConfiguration 
  • System.Data.Entity.ModelConfiguration.Configuration 
  • System.Data.Entity.ModelConfiguration.Conventions

Most Fluent API classes are suffixed with “Configuration“.

 

1. Entry Point – DbModelBuilder

The Fluent API functionalities are exposed through the “System.Data.Entity.DbModelBuilder” object. You can configure setting in the “OnModelCreating()” of “DBContext” and the “DbModelBuilder” object is passed as a parameter.

DbModelBuilder” has the following methods to get a basic configuration object for a specific type:

  • public ComplexTypeConfiguration<T> ComplexType<T>()
  • public EntityTypeConfiguration<T> Entity<T>()
public class ProductContext : DbContext
{
  public DbSet<Category> Categories { get; set; }

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    modelBuilder.Entity<Category>().Property(c => c.Name).IsRequired();
  }
}

 

2. System.Data.Entity.ModelConfiguration Namespace

The “ComplexTypeConfiguration” and “EntityTypeConfiguration” classes are defined in this namespace. By getting the instance of these objects, you can configure a complex type or an entity type.  Both types are derived from  “System.Data.Entity.ModelConfiguration.Configuration.StructuralTypeConfiguration“.

public abstract class StructuralTypeConfiguration<TStructuralType>
{
  public PrimitivePropertyConfiguration Property(Expression<func> e);
  public void Ignore(Expression<func> expression) // excludes a property from the model so that it will not be mapped to the database
}

EntityTypeConfiguration adds more methods to this:

public class EntityTypeConfiguration<TEntityType> : StructuralTypeConfiguration<TEntityType>
{
  public EntityTypeConfiguration<TEntityType> HasKey<TKey>(Expression<Func<TEntityType, TKey>> e);

  public OptionalNavigationPropertyConfiguration<TEntityType, TTargetEntity> HasOptional<TTargetEntity>(Expression<Func<TEntityType, TTargetEntity>> e);
  public RequiredNavigationPropertyConfiguration<TEntityType, TTargetEntity> HasRequired<TTargetEntity>(Expression<Func<TEntityType, TTargetEntity>> e);
  public ManyNavigationPropertyConfiguration<TEntityType, TTargetEntity> HasMany<TTargetEntity>( Expression<Func<TEntityType, ICollection<TTargetEntity>>> e);

  public EntityTypeConfiguration Map(Action<entitymappingconfiguration> entityMappingConfigurationAction);
}

 

3. PrimitivePropertyConfiguration

The “System.Data.Entity.ModelConfiguration.Configuration.PrimitivePropertyConfiguration” class represents the configuration of general properties of an entity type.

public class PrimitivePropertyConfiguration
{
  public PrimitivePropertyConfiguration HasColumnName(string columnName);
  public PrimitivePropertyConfiguration HasColumnOrder(Nullable columnOrder);
  public PrimitivePropertyConfiguration HasColumnType(string columnType);

  public PrimitivePropertyConfiguration HasDatabaseGeneratedOption(Nullable databaseGeneratedOption);
  public PrimitivePropertyConfiguration IsConcurrencyToken();
  public PrimitivePropertyConfiguration IsOptional();
  public PrimitivePropertyConfiguration IsRequired();
}

PrimitivePropertyConfiguration provides the basic configuration options for a database column.

 

4. Special Property Configuration Classes

The following classes are derived from “PrimitivePropertyConfiguration” and add some special options.

public class DateTimePropertyConfiguration : PrimitivePropertyConfiguration
{
  public DateTimePropertyConfiguration HasPrecision(byte value);
}

public class DecimalPropertyConfiguration : PrimitivePropertyConfiguration
{
  public DecimalPropertyConfiguration HasPrecision(byte precision, byte scale);
}

public abstract class LengthPropertyConfiguration : PrimitivePropertyConfiguration
{
  public LengthPropertyConfiguration HasMaxLength(Nullable value);
  public LengthPropertyConfiguration IsMaxLength();
  public LengthPropertyConfiguration IsFixedLength();
  public LengthPropertyConfiguration IsVariableLength();
}

LengthPropertyConfiguration” is for a binary array or a string but it is an abstract class, so the following 2 concrete classes are needed.

public class BinaryPropertyConfiguration : LengthPropertyConfiguration
{
  public BinaryPropertyConfiguration IsRowVersion();
}

public class StringPropertyConfiguration : LengthPropertyConfiguration
{
  public StringPropertyConfiguration IsUnicode()
}

 

5. Navigation Property Classes

There are configuration classes for a relationship between entities.

The “ForeignKeyNavigationPropertyConfiguration” is one of the most basic relationship classes. It is related with foreign key properties. It is derived from “CascadableNavigationPropertyConfiguration” that represents a relationship that can support cascade on delete functionality.

public abstract class CascadableNavigationPropertyConfiguration
{
  public void WillCascadeOnDelete();  // true by default
  public void WillCascadeOnDelete(bool value);
}

public class ForeignKeyNavigationPropertyConfiguration : CascadableNavigationPropertyConfiguration
{
  public CascadableNavigationPropertyConfiguration Map(Action configurationAction);
}

The “DependentNavigationPropertyConfiguration” is derived again from “ForeignKeyNavigationPropertyConfiguration“. The differences are:

  • ForeignKeyNavigationPropertyConfiguration : foreign key properties that are NOT exposed in the object model
  • DependentNavigationPropertyConfiguration : foreign key properties that are exposed in the object model
public class DependentNavigationPropertyConfiguration<TDependentEntityType> : ForeignKeyNavigationPropertyConfiguration
{
  public CascadableNavigationPropertyConfiguration HasForeignKey(Expression<func> foreignKeyExpression);
}

 

6. Entity Mapping Classes

Mapping classes are used to configure how entities, properties, and relationships map to database.

Configuration objects for entities, properties, and relationships have their own “Map()” method. By passing an Mapping object to the “Map()” method, you can configure the mapping.

EntityTypeConfiguration” has the following “Map()” method:

  • public EntityTypeConfiguration Map( Action<entitymappingconfiguration> entityMappingConfigurationAction)
public class EntityMappingConfiguration
{
  public void Properties(Expression<func> propertiesExpression); // the properties that will be included

  public NotNullConditionConfiguration Requires(Expression<func> property);
  public ValueConditionConfiguration Requires(string discriminator);
  public void ToTable(string tableName, string schemaName);
  public void ToTable(string tableName);
}

 

7. Association Mapping Classes

The navigation property classes provide the “Map()” method too. But they require a different mapping object type.

  • public CascadableNavigationPropertyConfiguration Map(Action configurationAction);

AssociationMappingConfiguration” is a base class for association mapping classes.

public abstract class AssociationMappingConfiguration { }

public sealed class ForeignKeyAssociationMappingConfiguration : AssociationMappingConfiguration
{
  public ForeignKeyAssociationMappingConfiguration MapKey(params string[] keyColumnNames);
  public ForeignKeyAssociationMappingConfiguration ToTable(string tableName);
}

public sealed class ManyToManyAssociationMappingConfiguration : AssociationMappingConfiguration
{
  public ManyToManyAssociationMappingConfiguration MapLeftKey(params string[] keyColumnNames);
  public ManyToManyAssociationMappingConfiguration MapRightKey(params string[] keyColumnNames);

  public ForeignKeyAssociationMappingConfiguration ToTable(string tableName);
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s