You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server不同表关联方案:EF Core下游戏多类型道具库存设计

EF Core 游戏道具存储最优实现方案

方案1:表 per 层次结构(TPH)单表存储(最适合中小体量游戏)

TPH是EF Core默认支持的多态映射方案,所有类型的道具都存在同一张Items表中:

  • 首先定义抽象基类Item,封装所有道具共有的属性:Id、ItemType(枚举:Weapon/Armor/Potion)、Cost
  • 子类分别继承基类,扩展自身独有属性:
    • Weapon子类:Weight、Damage、DamageType、MinStr
    • Armor子类:Weight、ArmorPoints、BodySlot、Hardness
    • Potion子类:Type、Effect、EffectAmount
  • EF Core会自动在表中生成Discriminator字段区分道具类型,空值的独有字段会自动处理
  • 背包表设计非常简单:PlayerInventory表只需要存PlayerId、ItemId、Count、SlotIndex,直接和Items表做外键关联即可
  • 查询全道具列表直接查Items表即可,EF Core会自动映射为对应的子类实例,不需要手动聚合多表数据
  • 优点:查询效率最高,关联逻辑最简单,背包操作无需判断类型
  • 适用场景:道具类型不超过10种,单表字段总数不超过30的中小项目

方案2:基表 + 类型扩展表(TPT,适合大型游戏道具体系)

如果道具类型多、独有属性多,不想单表出现大量空字段,可以用TPT模式:

  • 公共属性存在Items基表,每个道具类型单独建扩展表:Weapons、Armors、Potions,扩展表主键和Items表的Id做一对一外键关联
  • EF Core配置多态映射后,查询子类道具会自动做表联接,返回强类型子类实例
  • 背包表同样只需要关联Items表的Id,不需要存储类型标识,所有关联逻辑EF Core自动处理
  • 优点:表结构规整,无冗余空字段,扩展新道具类型只需要新增扩展表,不需要修改基表结构
  • 缺点:查询单类型道具会做表联接,性能略低于TPH

背包功能实现示例

两种方案下背包查询代码完全一致,不需要手动处理类型判断:

// 查询指定玩家的所有背包道具
var playerItems = await _dbContext.PlayerInventories
    .Where(x => x.PlayerId == currentPlayerId)
    .Include(x => x.Item)
    .OrderBy(x => x.SlotIndex)
    .ToListAsync();

// 遍历道具自动识别类型
foreach(var inventoryItem in playerItems)
{
    switch(inventoryItem.Item)
    {
        case Weapon weapon:
            // 处理武器逻辑
            break;
        case Armor armor:
            // 处理护甲逻辑
            break;
        case Potion potion:
            // 处理药水逻辑
            break;
    }
}

不推荐的方案

你之前想到的键值对存储、手动存类型+表ID的方案,会失去EF Core的强类型校验、外键约束、查询优化能力,后期维护成本极高,除非是海量道具的分布式场景,否则完全不需要用。

内容的提问来源于stack exchange,提问作者mummy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 13:54:03