1

I am trying to build a code first database with the Entity Framework with ASP.Net MVC 4.

I'm new to MVC & Entity Framework and I'm struggling with how to design my Class Objects.

I want a Members Class Like the one that follows, that has a data property of the AddressInformation Class :-

 public class Member
    {
        public virtual int MemberID { get; set; }
        public virtual string Forename { get; set; }
        public virtual string Surname { get; set; }
        public virtual int age { get; set; }
        public virtual AddressInformation Address { get; set; }
        public virtual string EmailAddress { get; set; }
        public virtual string HomePhoneNumber { get; set; }
        public virtual string MobileNumber { get; set; }
    }



public class AddressInformation
    {
        public virtual int MemberID { get; set; }
        public virtual string HouseNoName { get; set; }
        public virtual string StreetName { get; set; }
        public virtual string Town { get; set; }
        public virtual string County { get; set; }
        public virtual string PostCode { get; set; }
        public virtual string Country { get; set; }
    }

I also have another class that inherits from DbContext :-

public class CentralDataStore :DbContext
    {
        public DbSet<Member> Members { get; set; }
        public DbSet<AddressInformation> AddressInfo { get; set; }
    }

When I add the controller I am not getting the abilty to enter AddressInformation, only members info has populated through to my View's.

Anyone suggest the best method to attack this with? As I say, I'm new to MVC.

1
  • Have you tried to add public virtual int ID { get; set; } to the Addressinformtion class? Commented Dec 20, 2012 at 19:11

3 Answers 3

2

You do not need to make all of your properties virtual, only the ones used for navigation. And you need to setup up the relationship between Member and AddressInformation using the Fluency API. Also your primary key needs to be named Id or use an attribute or Fluency API to specify it is a primary key. You are also missing the id for mapping the Member to the AddressInformation. Here is what your class definition should look like.

public class Member
{
    public int ID { get; set; }
    public string Forename { get; set; }
    public string Surname { get; set; }
    public int age { get; set; }
    public virtual int AddressId { get; set; }
    public virtual AddressInformation Address { get; set; }
    public string EmailAddress { get; set; }
    public string HomePhoneNumber { get; set; }
    public string MobileNumber { get; set; }
}

public class AddressInformation
{
    public int ID { get; set; }
    public string HouseNoName { get; set; }
    public string StreetName { get; set; }
    public string Town { get; set; }
    public string County { get; set; }
    public string PostCode { get; set; }
    public string Country { get; set; }
}

Note I added the property AddressId to provide the mapping to the AddressInformation object/table. Configure the relationships in the Fluency API like this.

public class MemberConfig : EntityTypeConfiguration<Member>
{
    internal MemberConfig()
    {
        this.HasKey(m => m.ID);
        this.HasRequired(m => m.Address)
            .WithRequiredDependent(a => a.ID)
            .HasForeignKey(m => m.AddressId);

    }
 }

By setting up the foreign key relationship EF will automatically load the AddresssInformation into the Member object.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for this, brilliant explanation.
2

As far as I know the standard templates for generating the views does not implement the input fields for nested objects. But there is an option to expand the standard templates of MVC applications like in this link. There you can add the generation of input fields for nested classes if you are a fimilar to T4 templates.

Comments

2

You must be careful using this template, you can EASILY get a stackoverflow

Especially when using Entity Framework, when you have two entities with navigation properties that point to each other

The default Object template prevents recursion to a specific depth to prevent an infinite loop. I didn't like this so I wrote my own:

/Views/Shared/object.cshtml

@model object

@using System.Text;
@using System.Data;

@{
  ViewDataDictionary viewData = Html.ViewContext.ViewData;
  TemplateInfo templateInfo = viewData.TemplateInfo;
  ModelMetadata modelMetadata = viewData.ModelMetadata;

  System.Text.StringBuilder builder = new StringBuilder();

  string result;

  // DDB #224751
  if (templateInfo.TemplateDepth > 2) 
  { 
    result = modelMetadata.Model == null ? modelMetadata.NullDisplayText 
                                         : modelMetadata.SimpleDisplayText;
  }

  foreach (ModelMetadata propertyMetadata in modelMetadata.Properties
    .Where(pm => pm.ShowForEdit
           && pm.ModelType != typeof(System.Data.EntityState)
           && !templateInfo.Visited(pm))) 
  {
      builder.Append(Html.Editor(propertyMetadata.PropertyName).ToHtmlString());
  }

  result = builder.ToString();
}

@Html.Raw(result)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.