我被遗忘在我的遗产中:
首先让我解释一下我的问题的前提。 我的模特:
public class Person
{
[Key]
public int PersonId { get; set; }
[MaxLength(100)]
public string Name { get; set; }
}
public class SuperHero:Person
{
[MaxLength(100)]
public string SuperHeroName { get; set; }
public virtual ICollection<SuperPower> SuperPowers{ get; set; }
}
现在,我正在尝试为我的MVC网站创建我的viewModel,我有那些需要由显示/编辑Person / SuperHero的所有其他viewmodel继承的基类:
public class BasePersonViewModel
{
public string Name { get; set; }
ctors()
}
public class BaseSuperHeroViewModel : BasePersonViewModel
{
public List<string> SuperPowers{ get; set; }
ctors()
}
这里是我被困的地方,我试图只定义一个ViewModel,它可以用于Person和/或SuperHero的基类和访问属性(如果Person是超级英雄)。我一直在拔头发,但到目前为止只找到了一个我不喜欢的解决方案:
示例:
public class SomeViewModel<T> where T : BasePersonViewModel
{
public BasePersonViewModel obj;
public DateTime BirthDate { get; set; }
public SomeViewModel(Person data) //: base(data)
{
if (data is SuperHero)
obj = new BaseSuperHeroViewModel (data);
else
obj = new BasePersonViewModel(data);
}
}
虽然这样可行,但使用它真的不太性感。最重要的是,我可以拥有另一个继承自SomeViewModel的ViewModel。
有更清洁的方法来实现这一目标吗?
修改 我的主要目标是能够根据其中一个基类来转换我的SomeViewModel。让我们说在我的控制器中做一些事情:
if myclass is SomeViewModel (of type SuperHero)
究竟如何为Person / SuperHero数据库检索/检查
执行此操作var data = context.Person.first(w=> w.Id==1)
if (data is SuperHero)
..
我想这样,因为我想使用相同的viewmodel让我们说列出超级英雄和人,如果它是超级英雄则只是略有不同
编辑2 我试图避免使用整个Model.Obj能够直接用模型看到它...但我想的越多,我就越认为这是不可能真的......最重要的是我会喜欢在SomeViewModel中扩展一些其他的superHero特定属性(仅当SomeViewModel是一个超级英雄),而不是在BaseSuperHeroModel中声明的...让我们说在SomeViewModel中我只想要超级英雄的字段'ComesFromPlanet'。
编辑3 我想到了另一种方法,但它显然创建了各种ViewModel。 对于最一般的情况(所有人共享的所有字段),我会保留我的基础:
public class BasePersonViewModel
{
public string Name { get; set; }
ctors()
}
我界面特定的人:
public Interface IBaseSuperHero
{
[MaxLength(100)]
public string SuperHeroName { get; set; }
public List<string> SuperPowers{ get; set; }
}
我会像这样保留OtherViewModel:
public class SomeViewModel:BasePersonViewModel
{
Public datetime Birthdate {get;set;}
}
然后我会为其他Person继承者创建一个特定的SomeviewModel,并使用接口来获得旧属性和新属性。 例如:
public class SomeViewModelSuperHero:SomeViewModel, IBaseSuperHero
{
public string OriginalPlanet {get;set;}
}
这是一个干净的解决方案吗?
抱歉,我确定我不清楚这一点,但我试试了!
感谢您的投入和时间。
答案 0 :(得分:1)
像
这样的东西public class Person {
public virtual BasePersonViewModel MainViewModel {
get { return new BasePersonViewModel(this);}
}
}
public class SuperHero : Person {
public override BasePersonViewModel MainViewModel {
get { return new BaseSuperHeroViewModel(this);}
}
}
因此,如果所有人员类覆盖MainViewModel属性以返回相应的视图,则不需要
public BasePersonViewModel obj;
public SomeViewModel(Person data) {
if (data is SuperHero)
obj = new BaseSuperHeroViewModel (data);
else
obj = new BasePersonViewModel(data);
}
因为你可以拥有
public BasePersonViewModel obj;
public SomeViewModel(Person data) { obj = data.MainViewModel; }
然而,无论你有多少个人的子类,它都会有效。
答案 1 :(得分:1)
我试图只定义一个可以在Person和/或SuperHero的基类和访问属性中使用的ViewModel(如果Person是超级英雄)
假设当模型不是超级英雄时你会返回超级英雄属性的默认值,你可以这样做:
public class PersonOrSuperHeroViewModel {
private Person person;
private SuperHero superHero;
public PersonOrSuperHeroViewModel(Person personOrSuperHero) {
if (personOrSuperHero is SuperHero) superHero = personOrSuperHero;
person = personOrSuperHero;
}
public IsSuperHero { get { return superHero != null; } }
... // super-hero properties only work when IsSuperHero == true
}