Eric K
Eric K

Reputation: 726

Bind Complex Objects Within Model To Database

I've looked at a lot of articles this afternoon, but I can't seem to find a complete post that deals with complex objects within models that addresses what I'm attempting to do.

I am using a Code First approach, but do not have my models directly altering my database structure. Therefore, if changes occur to the database structure, I am manually changing the models.

With that said, I have the following table:

Name
Address1
Address2
Address3
City
State
Zip
Latitude
Longitude

I would like to build a model that looks like the following:

public class Person
{
  public string Name { get; set; }
  public Address Address { get; set; }
  public Coordinates Coordinates { get; set; }
}
public class Address {
  public string Address1 { get; set; }
  public string Address2 { get; set; }
  public string Address3 { get; set; }
  public string City { get; set; }
  public string State { get; set; }
  public string Zip { get; set; }
}
public class Coordinates
{
  public float Latitude { get; set; }
  public float Longitude { get; set; }
}

In my head, this seems like a tidy, objected oriented approach to 1-to-1 data coming back from the database. Instead of all these separate variable, similar data is grouped into subclasses.

My question is: How do I bind this complex model to my database using EF? If that is not possible, how do I write a custom binder to deal with data in this fashion.

Or am I thinking about this incorrectly. Is there a different way to approach this or should the data be structured differently?

EDIT

Based upon Jason Meckley's response below, this is the final code that I used to complete this task.

namespace MyNamespace
{
  public partial class Person
  {
    public string Name { get; set; }
    public Address Address { get; set; }
    public Coordinates Coordinates { get; set; }
  }
  [ComplexType]
  public class Address
  {
    [Display(Name = "Address")]
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string Address3 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
  }
  [ComplexType]
  public class Coordinates
  {
    public float Latitude { get; set; }
    public float Longitude { get; set; }
  }

  public partial class DATABASE_CONNECTION_NAME : DbContext
  {
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
      modelBuilder
          .Entity<Person>()
          .Property(x => x.Address.Address1)
          .HasColumnName("Address1");
      modelBuilder
          .Entity<Person>()
          .Property(x => x.Address.Address2)
          .HasColumnName("Address2");
      modelBuilder
          .Entity<Person>()
          .Property(x => x.Address.Address3)
          .HasColumnName("Address3");
      modelBuilder
          .Entity<Person>()
          .Property(x => x.Address.City)
          .HasColumnName("City");
      modelBuilder
          .Entity<Person>()
          .Property(x => x.Address.State)
          .HasColumnName("State");
      modelBuilder
          .Entity<Person>()
          .Property(x => x.Address.Zip)
          .HasColumnName("Zip");
      modelBuilder
          .Entity<Person>()
          .Property(x => x.Coordinates.Latitude)
          .HasColumnName("Latitude");
      modelBuilder
          .Entity<Person>()
          .Property(x => x.Coordinates.Longitude)
          .HasColumnName("Longitude");
    }
  }
}

Upvotes: 0

Views: 471

Answers (1)

Jason Meckley
Jason Meckley

Reputation: 7591

decorate Address and Coordinates with the attribute [ComplexType]. In your dbcontext subclass override OnModelCreating and map the complex properties to the appropriate columns.

By default complex objects would be mapped like this Address_Address and Coordinates_Latitude so you need to override the default mapping with something like

modelBuilder
          .Entity<Person>()
          .Property(x => x.Address.Address1)
          .HasColumnName("Address1");

Upvotes: 1

Related Questions