IT:AD:EF/CodeFirst/Entities/ComplexTypes

Summary

Complex Types are simply a way of Logically grouping db fields together so that they are easier to manipulate.

An example would be:

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

  public string First {get; set; }
  ...

  //Refer to a ComplexType (not same as a 1-1 relationship)
  //MUST: Cannot be marked Virtual to lazy load it:
  public Address Address { get; set; }  

  public User {
     //MUST: Will be required to be non-null before Saving, so factory up early:
     Address = new Address(); 
  }
}  

public class Address  
{  
  //MUST: no Id Property.
  //MUST: all properties are Scalar (not collections)
  public string Street { get; set; }  
  ...
}  

Although they are represented on screen as two distinct objects (albeit 1-1 relationship), they are saved to Db as

User [Id,First,…,AddressStreet,Address…]

  • MUST: No PK can be inferred, or defined via FluentAPI.
  • MUST: Only Scalar Properties (ie: no navigation properites to other Entities|Collections)
  • MUST: Not Referenced in an ICollection from anywhere.
  • MUST: Not marked as Virtual.
  • MUST: Required before saving.
    • Therefore, when Constructing/Factoring up User, set Address = new Address(); before Add/Saving.
  • COULD: If it needs to be forced (eg: the class has an Id), can be forced as follows:
    • using Attributes: [ComplexType]
    • using Fluent API within OnModelCreating():

Example:

modelBuilder.ComplexType<Address>();

* COULD: If we need to remap fields from default (Address_Street) use one of the following:

  • using Attributes: [Column]
  • using Fluent API within DbContext.OnModelCreating():

Example:

    `modelBuilder.ComplexType<Address>().Property(a=>a.Street).HasColumnName("Street");`
    `modelBuilder.Entity<Customer>().Property(c => c.Address.Street).HasColumnName("Customer_Street");`
  • /home/skysigal/public_html/data/pages/it/ad/code_first/entities/complextypes.txt
  • Last modified: 2023/11/04 03:39
  • by 127.0.0.1