实体框架继承与逻辑

时间:2013-05-17 22:04:59

标签: entity-framework oop entity-framework-4.1 game-engine ef-model-first

我一直在为现代MUD引擎创建原型。 MUD是一种简单的模拟形式,它提供了一种测试我正在研究的概念的好方法。这导致我在我的代码中的几个地方,事情,有点不清楚,设计正在受到质疑(可能是因为它有缺陷)。我首先使用模型(我可能需要更改它)并且我设计了一个自上而下的游戏对象架构。我可能这样做完全错了。

我所做的是创建一个MUDObject实体。这个实体实际上是我所有其他逻辑结构的基础,例如字符,它们的项目,种族等。我还创建了一组三个元类,用于逻辑目的以及属性,事件和标志。它们非常简单,都是从MUDObject继承的。

MUDObject类旨在为所有对象提供默认数据行为,包括删除死对象。自动清除楼层。这也是为了在需要时虚拟地促进这种逻辑。例如,检查房间以查看效果是否已结束并删除效果(删除标记)。

public partial class MUDObject
{
    public virtual void Update()
    {
        if (this.LifeTime.Value.CompareTo(DateTime.Now) > 0)
        {
            using (var context = new ReduxDataContext())
            {
                context.MUDObjects.DeleteObject(this);
            }
        }            
    }

    public virtual void Pause()
    {

    }

    public virtual void Resume()
    {

    }

    public virtual void Stop()
    {

    }        
}

我还有一个类World,它来自MUDObject并包含区域和空间(反过来包含游戏对象)并处理运行更新的操作的计时器。 (可能会被移动,放在这里好像它的作用会将它限制在当时只有世界上的物体。)

public partial class World
{
    private Timer ticker;


    public void Start()
    {
        this.ticker = new Timer(3000.0);
        this.ticker.Elapsed += ticker_Elapsed;
        this.ticker.Start();
    }

    private void ticker_Elapsed(object sender, ElapsedEventArgs e)
    {
        this.Update();
    }

    public override void Update()
    {
        this.CurrentTime += 3;
        // update contents
        base.Update();
    }

    public override void Pause()
    {
        this.ticker.Enabled = false;
        // update contents
        base.Pause();
    }

    public override void Resume()
    {
        this.ticker.Enabled = true;
        // update contents
        this.Resume();
    }

    public override void Stop()
    {            
        this.ticker.Stop();
        // update contents
        base.Stop();
    }
}

我很好奇两件事。

  1. 有没有办法重新编码上下文,以便它具有独立性 从MUDObject派生的每种类型的ObjectSets?

    • 即。 context.MUDObjects.Flags或context.Flags
    • 如果不是,我如何具体查询子类型?
  2. 我正在使用的更新/暂停/恢复/停止架构是否正常工作 直接放入EF实体时是否正确?给予比它更好 仅限数据?

    • 锁定是一个问题吗?
    • 部分类在制作时会自动提交更改吗?
    • 使用平面存储库并直接在游戏引擎中执行此操作会更好吗?

2 个答案:

答案 0 :(得分:2)

  

1)有没有办法重新编码上下文,以便它为从MUDObject派生的每个类型都有单独的ObjectSet?

是的,有。如果您决定要为所有实体定义基类,则通常会有一个 abstract 基类,该基类不是实体框架模型的一部分。该模型仅包含派生类型,上下文包含DbSet派生类型(如果它是DbContext),如

public DbSet<Flag> Flags { get; set; }

如果合适,您可以在类之间实现inheritance,但这将表达多态性,而不是实现与持久性相关的常见行为。

  

2)直接放入EF实体时,我正在使用的更新/暂停/恢复/停止架构是否正常工作?

没有。实体不应该对持久性有任何了解。上下文负责创建它们,跟踪它们的更改并更新/删除它们。我认为这也回答了关于自动提交更改的问题:没有。

<强>精化:

我认为提出单一责任原则是件好事。一般模式是

  • 让上下文填充商店中的对象
  • 让对象根据他们的职责(模拟)行事
  • 让上下文在必要时存储其状态

我认为Pause / Resume / Stop可能是MUD对象的责任。更新是一种完全不同的行动和责任。

现在我必须推测,但是你的World课程。你应该能够用一个简短的短语表达自己的责任,可能是“窝藏其他物品”或“界定界限”。我认为不应该做时机。我认为时机应该是一些核心效用的责任,它表示时间间隔已经过去。其他对象知道如何响应(例如,做一些状态更改,或上下文或存储库,保存更改)。

嗯,这只是如何考虑它的一个例子,可能远非正确。

另一件事是我认为保存更改应该不会像执行模拟的对象的状态更改那样频繁。它可能会大大减缓这个过程。也许应该在更长的时间间隔内或通过用户操作来完成。

答案 1 :(得分:0)

首先要说的是,如果您使用的是EF 4.1(因为它已被标记),您应该考虑使用5.0版(您需要为此创建一个.NET 4.5项目)

通过对性能的多项改进,您还可以从其他功能中受益。我将向您展示的代码将适用于5.0(我不知道它是否适用于4.1版本)

现在,让我们回答几个问题:

  

有没有办法重新编码上下文,以便它具有独立性   从MUDObject派生的每种类型的ObjectSets?如果不是我怎么能   具体查询子类型?           即context.MUDObjects.Flags或context.Flags

是的,你可以。但是调用有点不同,你不会有Context.Worlds,你只能用这种方式调用基类,如果你想得到一组Worlds(继承自MUDObject,你会调用:

var worlds = context.MUDObjects.OfType<World>();

或者你可以通过使用泛型直接做到:

var worlds = context.Set<World>();

如果以正确的方式定义继承,则应该有一个名为MUDObjects的抽象类,而其他所有类都应该从该类继承。 EF可以与此完美配合,您只需要做到正确。

  

我正在使用的更新/暂停/恢复/停止架构是否正常工作   什么时候直接放入EF实体?给出的不是数据   目的只是?

在这种情况下,我认为您应该考虑使用名为策略模式的设计模式,进行一些研究,它将适合您的对象。

  

锁定是一个问题吗?

取决于你如何开发系统......

  

部分类是否会自动提交更改   制成?

不明白这个问题......部分类就像常规类一样,但它们只是在不同的文件中,但是在编译时(或者在Design-Time事件,因为vshost.exe)它们实际上只是之一。

  

我是否会更好地使用平面存储库并在中执行此操作   游戏引擎直接?

很难回答,这一切都取决于游戏的要求,部署战略......