.NET MVC中如何向Animals的Dog列表添加不同品种的狗实例
问题分析与解决方案
你的核心问题在于原模型设计不符合“维护不同品种狗的列表”的需求,且错误地尝试将非泛型的Dog类当作泛型类使用。以下是具体的修正方案:
1. 重构模型设计(核心)
原Dog类是一个包含所有品种属性的容器,这种设计会导致每个Dog对象只有一个品种有值,其余都是null,无法实现“列表中每个元素是一只具体品种的狗”的目标。我们需要用继承体系来重构:
定义狗的基类
先创建一个所有狗品种的基类,用于统一列表类型:
public class BaseDog { public long Id { get; set; } // Entity Framework 所需的主键 public long AnimalsId { get; set; } // 关联Animals的外键 public Animals Animals { get; set; } // 导航属性,关联所属的Animals对象 }
重构各品种类
让每个狗品种继承自BaseDog,保留各自的属性:
// 注:原拼写Puddle修正为通用正确拼写Poodle public class Poodle : BaseDog { public string Name { get; set; } public DateTime DayOfBirth { get; set; } } // 注:原拼写Retriver修正为通用正确拼写Retriever public class Retriever : BaseDog { public string Name { get; set; } public int Age { get; set; } } public class Terrier : BaseDog { public string Color { get; set; } }
修改Animals类
将Dogs列表的类型改为List<BaseDog>,这样就能容纳所有品种的狗:
public class Animals { public long Id { get; set; } // 初始化列表,避免空引用异常 public List<BaseDog> Dogs { get; set; } = new List<BaseDog>(); }
2. 修正控制器代码
现在可以根据用户选择的品种,创建对应类型的狗实例并添加到列表中:
public ActionResult AddDog(long id, string breed, DateTime? date = null, string name = null, int? age = null, string color = null) { var animal = db.Animals.Find(id); if (animal == null) return HttpNotFound(); BaseDog newDog = breed.ToLower() switch { "poodle" => new Poodle { Name = name, DayOfBirth = date.GetValueOrDefault(DateTime.Now) }, "retriever" => new Retriever { Name = name, Age = age.GetValueOrDefault(0) }, "terrier" => new Terrier { Color = color }, _ => throw new ArgumentException("无效的狗品种") }; animal.Dogs.Add(newDog); db.SaveChanges(); return View(); }
3. Entity Framework 继承映射配置
如果使用EF Core/EF来持久化数据,需要配置**表每层次(TPH)**映射,让EF能识别不同的狗品种:
在你的DbContext类中重写OnModelCreating方法:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置BaseDog的鉴别器,用于区分不同品种 modelBuilder.Entity<BaseDog>() .HasDiscriminator<string>("Breed") .HasValue<Poodle>("poodle") .HasValue<Retriever>("retriever") .HasValue<Terrier>("terrier"); }
关键说明
- 原代码中
Dog<Puddle>的写法错误,因为你定义的Dog不是泛型类,重构后的继承体系从根本上解决了这个问题。 - 继承体系让每个狗对象都是具体品种的实例,列表可以统一用基类
BaseDog管理,完全符合你“维护不同类型狗的列表”的需求。
内容的提问来源于stack exchange,提问作者paciekFly
相关产品推荐
相关产品推荐

