【问题标题】:Creating Controller For a Derived Model using EF Code First and MVC3使用 EF Code First 和 MVC3 为派生模型创建控制器
【发布时间】:2013-05-26 20:22:58
【问题描述】:

我想知道如何为派生模型生成控制器。让我给你一张大图。有一个 Man 类,从中继承了 User 类。正如我在几个 EF 教程中所读到的,我没有在 DatabaseContext 类中定义 DbSet。因此,您可能知道在 SQL 上只会生成 一个表,其中包含除鉴别器列之外的 Man 和 User 类的所有属性。

问题出现在我试图为 User 找出一个 Controller 类时,但由于 DatabaseContext 中没有提到它,MVC 无法创建它并最终出现错误。因此,我为 Man 类创建了一个控制器,即 parent 类。我还在控制器中做了一些修改,以明确指向用户。我的意思是,使用 OfType 等等。但是当我来到基于 MVC 脚手架创建的视图时,我找不到任何用户属性,那些专用于这个类的属性。

以下是 Man 类:

public class Man
{
    [Key]
    [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
    public long ID { get; set; }
    //------------------------------------------------------------//
    [Required, MaxLength(20)]
    [LocalizedAttribute("FName")]
    public string FName { get; set; }
    //------------------------------------------------------------//
    [Required, MaxLength(20)]
    [LocalizedAttribute("LastName")]
    public string LastName { get; set; }
    //------------------------------------------------------------//
    [Required]
    [RegularExpression("^[0-9]+$", ErrorMessageResourceName = "ErrorOnlyNumbers", ErrorMessageResourceType = typeof(MAHAL_E_MA_Model.Properties.Resources))]
    [LocalizedAttribute("Mobile")]
    public string Mobile { get; set; }
    //------------------------------------------------------------//
    [LocalizedAttribute("Phone")]
    [RegularExpression("^[0-9]+$", ErrorMessageResourceName = "ErrorOnlyNumbers", ErrorMessageResourceType = typeof(MAHAL_E_MA_Model.Properties.Resources))]
    public string HomePhone { get; set; }
    //------------------------------------------------------------//
    [RegularExpression("^[0-9]+$")]
    [LocalizedAttribute("IDCardNumber")]
    public string IDCardNumber { get; set; }
    //------------------------------------------------------------//
    [RegularExpression("^[0-9]+$")]
    [LocalizedAttribute("NationalCode")]
    public string NationalCode { get; set; }
    //------------------------------------------------------------//
    [MaxLength(10)]
    [LocalizedAttribute("DOB")]
    public int DOB { get; set; }
    //------------------------------------------------------------//
    [Required]
    public int CityID { get; set; }
    [ForeignKey("CityID")]
    public virtual City CityParent { get; set; }
    //------------------------------------------------------------//
    [MaxLength(100)]
    [LocalizedAttribute("Address")]
    public string Address { get; set; }
    //------------------------------------------------------------//
    [LocalizedAttribute("PostalCode")]
    public string PostalCode { get; set; }
    //------------------------------------------------------------//
    [MaxLength(255)]
    [LocalizedAttribute("PhotoPath")]
    public string PhotoPath { get; set; }
}

这里是用户类:

public class User : Man
{
    [MaxLength(20)]
    [LocalizedAttribute("Username")]
    public string UserName { get; set; }
    //------------------------------------------------------------//
    [DataType(DataType.Password)]
    [MaxLength(100), MinLength(6, ErrorMessageResourceType = typeof(MAHAL_E_MA_Model.Properties.Resources), ErrorMessageResourceName = "ErrorPasswordLength")]
    [LocalizedAttribute("Password")]
    public string Password { get; set; }
    //------------------------------------------------------------//
    [DataType(DataType.Password)]
    [Compare("Password", ErrorMessageResourceType = typeof(MAHAL_E_MA_Model.Properties.Resources), ErrorMessageResourceName = "ErrorConfirmPassword")]
    [LocalizedAttribute("ConfirmPassword")]
    public string ConfirmPassword { get; set; }
    //------------------------------------------------------------//
    [DataType(DataType.EmailAddress, ErrorMessageResourceType = typeof(MAHAL_E_MA_Model.Properties.Resources), ErrorMessageResourceName = "ErrorEmailInvalid")]
    [MaxLength(20)]
    [RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")]
    [LocalizedAttribute("Email")]
    public string Email { get; set; }
    //------------------------------------------------------------//
    [MaxLength(30)]
    [LocalizedAttribute("Title")]
    public string Title { get; set; }
    //------------------------------------------------------------//
    [MaxLength(10)]
    [LocalizedAttribute("HireDate")]
    public int HireDate { get; set; }
    //------------------------------------------------------------//
    [LocalizedAttribute("ReportsTo")]
    public long ReportsTo { get; set; }
    [ForeignKey("ReportsTo")]
    public virtual IList<User> ReportsChild { get; set; }
}

此外,我确实在我的控制器中使用了 OfType 并这样查看:

//
    // GET: /User/

    public ViewResult Index()
    {
        //var mans = db.Mans.Include(m => m.CityParent);
        return View(unitOfWork.UserRepository.Get(orderBy: us => us.OrderByDescending(u => u.ID)).OfType<User>().ToList());
    }

 // POST: /User/Create

    [HttpPost]
    public ActionResult Create(Man man)
    {
        if (ModelState.IsValid)
        {
            //db.Mans.Add(man);
            //db.SaveChanges();
            MAHAL_E_MA_Model.POCO.User user = (MAHAL_E_MA_Model.POCO.User)man;
            unitOfWork.UserRepository.InsertData(user);
            unitOfWork.UserRepository.Save();
            return RedirectToAction("Index");  
        }

       // ViewBag.CityID = new SelectList(db.Cities, "CityID", "Name", man.CityID);
        return View(man);
    }

在视图中:

 @foreach (var item in Model)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.FName.OfType<MAHAL_E_MA_Model.POCO.User>())
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.LastName.OfType<MAHAL_E_MA_Model.POCO.User>())
        </td>

        <td>
            @Html.DisplayFor(modelItem => item.Mobile.OfType<MAHAL_E_MA_Model.POCO.User>())
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.HomePhone.OfType<MAHAL_E_MA_Model.POCO.User>())
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.IDCardNumber.OfType<MAHAL_E_MA_Model.POCO.User>())
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.NationalCode.OfType<MAHAL_E_MA_Model.POCO.User>())
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.DOB)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.CityParent.Name.OfType<MAHAL_E_MA_Model.POCO.User>())
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Address.OfType<MAHAL_E_MA_Model.POCO.User>())
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.PostalCode.OfType<MAHAL_E_MA_Model.POCO.User>())
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.PhotoPath.OfType<MAHAL_E_MA_Model.POCO.User>())
        </td>
        <td>
            @Html.ActionLink(GeneralResource.Edit, "Edit", new { id = item.ID }) |
            @Html.ActionLink(GeneralResource.ViewDetails, "Details", new { id = item.ID }) |
            @Html.ActionLink(GeneralResource.Delete, "Delete", new { id = item.ID })
        </td>
    </tr>

顺便说一句,我从来没有提到过DbSet&lt;User&gt;,而提到过DbSet&lt;Man&gt;。原因; EF 将创建一张表,其中包含 User 和 Man 的所有属性,称为 Man 表。可以使用 Discriminator 列区分不同的继承类,例如 Customer(本问题中未提及)和 User。

对不起,如果故事变得很长,但是我该如何处理呢?也就是说,我如何才能在视图中拥有 用户属性? 我是否必须自己添加它们,但如果是这样,我无法访问它们,因为分散了一些 DisplayFor() 包含在创建数据输入表单的 foreeach 循环。

希望我能成功转移问题.. 谁可以帮我这个事? 问候,

【问题讨论】:

  • 请显示您的课程代码和您使用OfType的代码。 (请使用段落)。
  • 为什么你在context 中“没有定义DbSet”?
  • @GertArnold 和@haim770;很抱歉实际上延迟了,因为我提出的问题是深夜......现在制作一些段落,带来代码,以及为什么不提及 DbSet.. 希望你能帮助我
  • 您使用实体框架并将所有表格拖到 .edmx 文件中是对的。
  • 不,不是。我首先使用 EF 代码。

标签: c# asp.net-mvc-3 ef-code-first


【解决方案1】:

您似乎正在尝试为每个层次结构映射一个表。您可能需要根据鉴别器值定义到 Man 的映射:

   public class MyDbContext: DbContext
   {
     // Constructor here


     public DbSet<Man> Man {get;set;} 

     protected override void OnModelCreating(DbModelBuilder modelBuilder)
     {
         modelBuilder.Entity<Man>().Map<User>(c => c.Requires("UserTypeId").HasValue(1));

     }

}

然后您的存储库可以查询用户的上下文并将用户对象返回给视图。将视图更改为@model IList&lt;User&gt;,您应该能够将 User 与 Man 属性一起使用。您可以映射其他类型,例如modelBuilder.Entity&lt;Man&gt;().Map&lt;Customer&gt;(c =&gt; c.Requires("UserTypeId").HasValue(2)

我假设您使用的是 EF 5,并且有一个名为 UserTypeId 的鉴别器列。

希望对您有所帮助!

【讨论】:

  • 谢谢你,你刚刚明白了,但是在 DatabaseCONtext 中定义 DbSet 是必须的吗?当我学习教程时,没有必要这样做..
  • 我已经按照你的建议做了,但现在面临一个新错误:“类型 MAHAL_E_MA_Model.POCO.Man 不能用作泛型类型或方法中的类型参数 'TDerived'...没有从 MAHAL_E_MA_Model.POCO.Man 到 MAHAL_E_MA_Model.POCO.User 的隐式引用转换”你有什么想法吗?
  • 对不起,我的继承倒退了。我更正了代码示例。您的控制器应该使用 User 存储库从 Man 表中查询 User 对象。
  • @JaySkill84:我已经知道了。但你知道问题出在视图文件上!!我无法访问从那里的人派生的用户类属性。即使考虑到您所做的更正。那么现在有什么想法了吗?
  • 您是否在视图顶部指定了模型?视图的顶部应该有 @model IList&lt;User&gt; 我对答案进行了编辑,我的类型和大小写错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多