代码之家  ›  专栏  ›  技术社区  ›  user875234

如何将数据库中的字符串映射到模型中的枚举,而不引入第二个属性?

  •  0
  • user875234  · 技术社区  · 7 年前

    我的数据库有这样一个表:

    - CatId INT PK
    - Name VARCHAR(100)
    - FavoriteToy VARCHAR(100)
    

    我的代码如下所示:

    猫反恐精英

    public int CatId { get; set; }
    public string Name { get; set; }
    public Toy FavoriteToy {get; set; }
    

    静态变量。反恐精英

    public enum Toy { Box, Ball, StuffedAnimal }
    

    在一个规范化的数据库中,我将使用数据库中的一个查找表来存储所有玩具,然后Cats表将只存储一个ToyId。但在这种情况下,将FavoriteToy存储为字符串要容易得多,即使它是多余的。

    问题是我不知道如何在不创建第二个枚举的情况下将数据库中的字符串转换为代码中的枚举 FavoriteToyString 财产和拥有 FavoriteToy 只需是一个返回从 偏爱约会 .

    我听说在当前版本的实体框架中,这可能是可能的。这是真的吗?你能告诉我怎么做吗?

    1 回复  |  直到 7 年前
        1
  •  0
  •   Jack    7 年前

    您可以使用DTO类和 automapper 要解决您的问题:)

        2
  •  0
  •   Steve Py    7 年前

    一般来说,查找表引用是更好的选择,因为您的数据可以符合引用完整性。也就是说,没有你的枚举中不包含的玩具的猫记录。(尽管你的枚举需要与玩具表保持同步。)您可以使用映射技巧将EF配置为将枚举存储为字符串:

    public class Cat
    {
      [Key]
      public int CatId { get; set; }
      public string Name { get; set; }
    
      [Column("FavoriteToy")]
      public string FavoriteToyMapped { get; set; }
    
      [NotMapped]
      public Toy FavoriteToy 
      {
        get { return (Toy)Enum.Parse(typeof(Toy), FavoriteToyMapped); }
        set { FavoriteToyMapped = value.ToString(); }
      }
    }
    

    这种方法需要注意的是,如果您可能使用Linq to实体来过滤猫最喜欢的玩具,则需要在查询表达式中引用FavoriteToyMapped值,因为EF/DB不知道FavoriteToy是什么。

    即。 猫最喜欢的玩具是“纱线”

    var catsThatLoveYarn = context.Cats.Where(c => c.FavoriteToyMapped == Toys.Yarn.ToString()).ToList();
    // not
    var catsThatLoveYarn = context.Cats.Where(c => c.FavoriteToy == Toys.Yarn).ToList();
    // Will error because EF doesn't map that property.
    

    使用实体实例后,如果实体集已从数据库中撤回,则可以使用FavoriteToy进一步访问/优化查询。如果过早使用未知字段,EF会尝试编写一个查询,请谨慎并做好准备。

    var threeYearOldCats = context.Cats.Where(c => c.Age == 3).ToList();
    var threeYearOldCatsThatLoveYarn = threeYearOldCats.Where(c => c.FavoriteToy == Toys.Yarn).ToList();
    

    这没关系,因为。在第一个查询中,ToList()执行EF to SQL,因此三岁的猫现在是本地的 List<Cat> 猫的实体,而不是 IQueryable<Cat> .