0

我在这里被困在我的遗产膨胀中:

首先让我解释一下我的问题的前提。我的模型:

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 网站创建我的视图模型,我有那些需要被所有其他视图模型继承的基类,这些视图模型显示/编辑一个人/超级英雄:

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 db retrival/check 做的

var data = context.Person.first(w=> w.Id==1)
if (data is SuperHero)
..

我想要这个,因为我想使用相同的视图模型让我们假设列出超级英雄和人,如果它是超级英雄,则显示略有不同

编辑 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;}
}

这是一个干净的解决方案吗?

对不起,我确定我不清楚这一点,但我试试!

感谢您的投入和时间。

4

2 回答 2

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; }

无论您拥有多少人,这都会起作用。

于 2013-04-03T19:25:14.573 回答
1

我试图只定义一个 ViewModel 可以使用,而不管 Person 和/或 SuperHero 的基类和访问属性(如果 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
}
于 2013-04-03T19:36:51.783 回答