【问题标题】:EF5 MVC4 Child/Parent navigation propertiesEF5 MVC4 子/父导航属性
【发布时间】:2013-07-25 18:18:31
【问题描述】:

我有 3 个类可以是众多父类的子类。有没有办法在不为每个可能的父类型添加导航属性的情况下找到子父类的 ID/类型?

例如: 我正在制作一个基于浏览器的太空策略游戏。父类(Fleet、Asteroid、Planet)继承自此处定义的名为“OwnableSpaceObject”的类:

public abstract class OwnableSpaceObject : SpaceObject
{
    public int? UserId { get; set; }
    public int? ResourcesId { get; set; }

    [ForeignKey("UserId")]
    public virtual UserProfile User { get; set; }

    [ForeignKey("ResourcesId")]
    public virtual Resources Resources { get; set; }

    public virtual ICollection<Structure> Structures { get; set; }
    public virtual ICollection<Ship> Ships { get; set; }
}

鉴于每个子类(Resources、Structure、Ship)都可以属于从该基类继承的任何一个父类,实体框架为它们提供了“Asteroid_Id”、“Planet_Id”和“Fleet_Id”等列“我试图避免这种情况,因为如果我添加更多父类,我将在表中拥有 3-20 多个可空的 'Parent_Id' 列(这是不好的做法,不是吗?)。

我希望能够拉出 Parent 的对象,这样我就可以从孩子那里访问 Id 之类的东西,这样我就可以看到他们的兄弟姐妹是什么,并且我想尽量避免为他们父母的每一种可能性放置一个导航属性.这方面的一个例子是,在 Resources 类中,我需要能够查看父级有多少 StructuresShips 以便计算最大金属存储和金属聚集率。因此,Resources/Structures/Ships 都是同一父级下的兄弟姐妹,父级可能是 Fleet/Asteroid/Planet

我希望这一切都是有道理的,并且这不是太荒谬的请求:)。谁能指出我正确的方向?

为澄清类结构而编辑:

OwnableSpaceObject 具有 Resources/Ships/Structures 作为属性(每个都是它们自己的类,从无继承,Ships 和 Structures 是 ICollections)

舰队/小行星/行星继承自 OwnableSpaceObject

所以基本上我有:

public Fleet : OwnableSpaceObject { //fleet specific stuff }
public Asteroid: OwnableSpaceObject { //asteroid specific stuff }
public Planet: OwnableSpaceObject { //planet specific stuff }

这些类中的每一个都有一个 ICollection of Stuctures 和 Ships。实体框架为从 OwnableSpaceObject 继承的每个类在 Structure/Ship 表中创建一个类似“Asteroid_Id”、“Planet_Id”和“Fleet_Id”的列。

【问题讨论】:

  • 你能解释一下你的类图吗?我对继承什么感到困惑。
  • @CharlieBrown 我不确定我的后期修订是否对您有帮助。我不善于解释我的感受。让我知道你的想法。我觉得 Resources 类应该能够找出 MaxMetal/MetalGatherRate 但看起来我需要让 Fleet/Asteroid/Planet 在 Resources 类之外自行解决这个问题。

标签: c# asp.net-mvc entity-framework


【解决方案1】:

一般来说,如果 Resources/Structures/Ships 继承自一个接口,例如

public interface IResourceItem
{
   double MaxMetalStorage{get;}
   double MetalGatherRate{get;}
}

你可以这样修改父类

public class Resources
{
    public IList<IResourceItem> ResourceItems {get; set;}

    public double GetTotalMetalStorage(){
        return this.ResourceItems.Sum(x => x.MaxMetalStorage);
    }
}

【讨论】:

  • 嗯,这可能是比我采用的更好的方法。我以前从未做过接口。我需要再调查一下。
  • 子类化也可以代替接口工作。有很多方法。
猜你喜欢
  • 2012-11-01
  • 2014-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多