Introduction
In Entity Framework Code First, scalar properties are only mapped to the columns in database if they can be converted to EDM(Entity Data Model) supported types. If a property is of a type which is not convertable to a type that is supported by the EDM then that property is ignored by Code First while creating the database.
The following is the list of all valid EDM supported types:
EDM Supported Types:
Binary, Boolean, Byte, DateTime, DateTimeOffset, Decimal, Double, Guid, Int16, Int32, Int64, SByte, Single, String, Time.
Property mapping
The followings are few cases for property mapping:
- A public property having getters and setters is automatically mapped.
- The setter of a property can be exposed to lesser scope by changing the access specifier to: internal, protected, private, etc. but the getter must be public to map the property automatically.
- The nonpublic properties must be mapped using the Fluent API configuration.
Configuration for Nonpublic Properties
Internal property access specifier
Let's assume that we have a Payment class and it has a property PaymentDate having access specifier as internal. Both Payment.cs and Context.cs(it inherits DbContext) files lies in the same assembly. To include the PaymentDate property in the model we can write it within OnModelCreating() method as follows:
modelBuilder.Entity<Payment>().Property(p => p.PaymentDate);
But if both Payment.cs and Context.cs files lies in two different assemblies then to include the PaymentDate property in the model we could add PaymentConfiguration class(inheriting EntityTypeConfiguration<Payment>) in the same assembly where the Payment.cs file is present. The configurations can be performed inside the PaymentConfiguration class and then it will be registered inside the OnModelCreating() method of Context.cs file like follows:
modelBuilder.Configurations.Add(new PaymentConfiguration());
Protected/Private property access specifiers
If you want to map a property having access specifier as protected or private then the configuration class must be nested within the entity class.
Lets consider an example where we have a Payment class and it has a private property PaymentDate.
To map the PaymentDate property we can modify the PaymentConfiguration as follows:
public class Payment
{
public int PaymentId { get; set; }
private DateTime PaymentDate { get; set; }
public class PaymentConfiguration : EntityTypeConfiguration<Payment>
{
public PaymentConfiguration()
{
Property(b => b.PaymentDate);
}
}
}
Exclude Property from Model
By convention, all properties having public getter and setters are mapped automatically. But you can prevent the mapping of a property by either of the following ways:
- Using [NotMapped] Data Annotation attribute
- Using Ignore() Fluent API method
Using [NotMapped] Data Annotation attribute
Add the [NotMapped] attribute above the property which you want to exclude from the model like:
[NotMapped]
public string Total { get; set; }
This is useful when you have a property which contains values calculated by doing some businesss processing and you don't want to create a column for this property in the database.
Using Ignore() Fluent API method
You can use Ignore() Fluent API method to exclude a property from the model.
If you want to specify it on DbModelBuilder you can try like:
modelBuilder.Entity<Payment>().Ignore(p => p.Total);
The same you can specify using EntityTypeConfiguration<T> as follows:
public class ExcludeConfiguration : EntityTypeConfiguration<Payment>
{
public ExcludeConfiguration()
{
Ignore(p => p.Total);
}
}