使用EF Code First和MVC3为派生模型创建控制器

时间:2013-05-26 20:22:59

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

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

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

以下是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<User>,而是提到DbSet<Man>。原因; EF将创建一个包含所有User和Man属性的表,称为Man表。使用Discriminator列可以在不同的继承类(例如Customer(本问题中未提及)和用户之间)进行Distingushing。

很抱歉,如果故事很长,但我该如何处理呢?也就是说,我怎样才能在视图中拥有用户属性?我是否必须在自己身上添加它们但是如果是这样我就没有任何访问权限,因为它们分散了一些DisplayFor()创建数据输入表单的foreeach循环。

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

1 个答案:

答案 0 :(得分:0)

看起来你正在尝试为每个层次结构映射做一个表。您可能需要根据鉴别器值定义到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));

     }

}

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

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

希望有所帮助!