为什么在使用通过支持MVC 5 / EF 6(继承)派生类创建的视图和控制器时会收到错误?

时间:2015-06-23 17:59:29

标签: entity-framework inheritance asp.net-mvc-5

为什么在使用通过支持MVC 5 / EF 6(继承)派生类创建的视图和控制器时会收到错误?

我的背景:我是以前的Powerbuilder(客户端/服务器程序员),正在努力学习基于Web的编程。 我选择了ASP.NET并购买了MSDN许可证以使用Visual Studio 2013,并且已经通过书籍,在线培训和计算机上的旧版黑客进行学习。 最好的测试是创建一些示例应用程序,所以我在这里。我正在学习MVC和Code First EF,因为有很多好的信息和样本。 但是,我仍然坚持我的继承示例。

我有3个类:AircrewMember派生自Airman派生自Person。他们编译没有错误。 我有一个类DbInitializer所以“Code First”将创建数据库。我实际上使用SQL脚本来加载我的测试数据。 我有一个类StanEvalDb用于数据库上下文信息。 我已经从web.config中包含了相关信息。

问题:

当我使用scaffolding创建一个控制器和基于Airman类(派生自Person)的视图时,结果会返回错误。

        Airman airman = db.People.Find(id);

错误1
无法将类型'SEMX1.Entities.Person'隐式转换为'SEMX1.Entities.Airman'。存在显式转换(您是否错过了演员?)     D:\ Projects \ VC2013 \ 2015 \ 06-Jun \ SEMX1 \ SEMX1.Web \ Controllers \ AirmenController.cs 31 29 SEMX1.Web

我想我理解每个层次结构表(TPH),并且实际上只创建了一个表(People)来容纳所有“3”表。
我不知所措......我用Google搜索并阅读了很多文章,但我不知道如何继续。有没有人看过这个或尝试过这个? 我认为我忽视了一些简单的事情,但我没有想法。任何帮助将不胜感激!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SEMX1.Entities
{
    public class Person
    {
        public virtual int PersonId { get; set; }

        [DisplayName("First Name* ")]
        [StringLength(40)]
        [Required(ErrorMessage = "The First Name field is required.")]
        public virtual string PersonFirstName { get; set; }

        [DisplayName("Middle Initial ")]
        [StringLength(2)]
        public virtual string PersonMidInit { get; set; }

        [DisplayName("Last Name* ")]
        [StringLength(50)]
        [Required(ErrorMessage = "The Last Name field is required.")]
        public virtual string PersonLastName { get; set; }

        [DisplayName("SSN* ")]
        [StringLength(11)]
        [Required(ErrorMessage = "The SSN field is required.")]
        public virtual string PersonSSN { get; set; }

        [DisplayName("DOB* ")]
        [Required(ErrorMessage = "The DOB field is required.")]
        public virtual DateTime? PersonDOB { get; set; }

        public virtual int CivilRankId { get; set; }

        //public virtual int LifeEventId { get; set; }
        public virtual ICollection<LifeEvent> LifeEvents { get; set; }
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SEMX1.Entities
{
    public class Airman : Person
        {
            public virtual int MilitaryRankId { get; set; }
            public virtual int MilitaryUnitId { get; set; }
            public virtual int AfscId { get; set; }

            public virtual ICollection<CareerEvent> CareerEvents { get; set; }
        }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SEMX1.Entities
{
    public class AircrewMember : Airman
    {
        public virtual int AviationTypeId { get; set; }
        public virtual int AirMissionId { get; set; }
        public virtual int AircraftId { get; set; }
        public virtual int CrewPositionId { get; set; }
        public virtual int ExperienceRatingId { get; set; }
        public virtual int AirmanshipId { get; set; }
        public virtual int TacticalDayRatingId { get; set; }
        public virtual int TacticalNightRatingId { get; set; }

        public virtual ICollection<AircrewEvent> AircrewEvents { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using SEMX1.Entities;
using System.IO;

namespace SEMX1.Web.DataContexts
{
    public class DbInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<StanEvalDb>
    {
        protected override void Seed(StanEvalDb context)
        {
            base.Seed(context);

            // using SQL scripts to load database with test data
            // easier way to get around identity key field problems


        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using SEMX1.Entities;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace SEMX1.Web.DataContexts
{
    public class StanEvalDb : DbContext
    {
        public StanEvalDb() : base("StanEvalContext")
        {
            Database.SetInitializer<StanEvalDb>(new DbInitializer());
        }

        public DbSet<Person> People { get; set; }
        public DbSet<LifeEvent> LifeEvents { get; set; }
        public DbSet<CivilRank> CivilRanks { get; set; }
        public DbSet<MilitaryRank> MilitaryRanks { get; set; }
        public DbSet<MilitaryUnit> MilitaryUnits { get; set; }
        public DbSet<MilUnitType> MilUnitTypes { get; set; }
        public DbSet<AFSC> AFSCList { get; set; }
        public DbSet<CareerEvent> CareerEvents { get; set; }
       public DbSet<Airman> Airmen { get; set; }
        public DbSet<AviationType> AviationTypes { get; set; }
        public DbSet<AirMission> AirMissions { get; set; }
        public DbSet<Aircraft> AircraftList { get; set; }
        public DbSet<CrewPosition> CrewPositions { get; set; }
        public DbSet<ExperienceRating> ExperienceRatings { get; set; }
        public DbSet<Airmanship> AirmanshipList { get; set; }
        public DbSet<TacticalDayRating> TacticalDayRatings { get; set; }
        public DbSet<TacticalNightRating> TacticalNightRatings { get; set; }
        public DbSet<AircrewEvent> AircrewEvents { get; set; }
        public DbSet<AircrewMember> Aircrew { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

            //modelBuilder.Entity<Person>()
            //    .HasMany(p => p.LifeEvents).WithMany(l => l.People)
            //    .Map(t => t.MapLeftKey("PersonID")
            //    .MapRightKey("LifeEventID")
            //    .ToTable("LifeEventPersons"));

            //modelBuilder.Entity<Airman>()
            //    .HasMany(a => a.CareerEvents).WithMany(c => c.Airmen)
            //    .Map(t => t.MapLeftKey("PersonID")
            //    .MapRightKey("CareerEventID")
            //    .ToTable("CareerEventAirmen"));

            //modelBuilder.Entity<AircrewMember>()
            //    .HasMany(a => a.AircrewEvents).WithMany(c => c.Aircrew)
            //    .Map(t => t.MapLeftKey("PersonID")
            //    .MapRightKey("AircrewEventID")
            //    .ToTable("AircrewEventAircrew"));

        }
    }
}
Web.config (Pertinent Information)

<configuration>
  <configSections>
    <section name="entityFramework" 
             type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
             requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="StanEvalContext"
      connectionString="Data Source=REDCARBOSS2-LAP\RCB2SRV2012;Initial Catalog=DB_25213_SEMX1;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" 
                type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using SEMX1.Entities;
using SEMX1.Web.DataContexts;

namespace SEMX1.Web.Controllers
{
    public class AirmenController : Controller
    {
        private StanEvalDb db = new StanEvalDb();

        // GET: Airmen
        public ActionResult Index()
        {
            return View(db.People.ToList());
        }

        // GET: Airmen/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Airman airman = db.People.Find(id);
            if (airman == null)
            {
                return HttpNotFound();
            }
            return View(airman);
        }

        // GET: Airmen/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Airmen/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "PersonId,PersonFirstName,PersonMidInit,PersonLastName,PersonSSN,PersonDOB,CivilRankId,MilitaryRankId,MilitaryUnitId,AfscId")] Airman airman)
        {
            if (ModelState.IsValid)
            {
                db.People.Add(airman);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(airman);
        }

        // GET: Airmen/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Airman airman = db.People.Find(id);
            if (airman == null)
            {
                return HttpNotFound();
            }
            return View(airman);
        }

        // POST: Airmen/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "PersonId,PersonFirstName,PersonMidInit,PersonLastName,PersonSSN,PersonDOB,CivilRankId,MilitaryRankId,MilitaryUnitId,AfscId")] Airman airman)
        {
            if (ModelState.IsValid)
            {
                db.Entry(airman).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(airman);
        }

        // GET: Airmen/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Airman airman = db.People.Find(id);
            if (airman == null)
            {
                return HttpNotFound();
            }
            return View(airman);
        }

        // POST: Airmen/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Airman airman = db.People.Find(id);
            db.People.Remove(airman);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

错误说它无法隐式转换并要求您显式转换。尝试替换它:

Airman airman = db.People.Find(id);

使用:

Airman airman = (Airman)db.People.Find(id);