1

我正在尝试使用带有 ASP.Net MVC 4 的实体框架构建代码优先数据库。

我是 MVC 和实体框架的新手,我正在努力设计我的类对象。

我想要一个像下面这样的成员类,它具有 AddressInformation 类的数据属性:-

 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; }
    }

我还有另一个继承自 DbContext 的类:-

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

当我添加控制器时,我无法输入地址信息,只有成员信息已填充到我的视图中。

任何人建议最好的方法来攻击这个?正如我所说,我是 MVC 的新手。

4

3 回答 3

2

据我所知,用于生成视图的标准模板没有实现嵌套对象的输入字段。但是有一个选项来扩展 MVC 应用程序的标准模板,就像在这个链接中一样。如果您熟悉 T4 模板,则可以在此处为嵌套类添加输入字段的生成。

于 2012-12-20T19:18:38.830 回答
2

你必须小心使用这个模板,你可以很容易地得到一个stackoverflow

尤其是在使用 Entity Framework 时,当您有两个具有导航属性的实体相互指向时

默认Object模板防止递归到特定深度以防止无限循环。我不喜欢这样,所以我自己写了:

/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)
于 2012-12-20T19:53:28.047 回答
2

您不需要将所有属性设为虚拟,只需将用于导航的属性设为虚拟即可。您需要使用 Fluency API 设置 Member 和 AddressInformation 之间的关系。此外,您的主键需要命名为 Id 或使用属性或 Fluency API 来指定它是主键。您还缺少用于将成员映射到 AddressInformation 的 id。这是您的类定义的样子。

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; }
}

注意我添加了属性 AddressId 以提供到 AddressInformation 对象/表的映射。像这样在 Fluency API 中配置关系。

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);

    }
 }

通过设置外键关系,EF 会自动将 AddresssInformation 加载到 Member 对象中。

于 2012-12-20T21:47:38.380 回答