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

使用实体框架生成非主键ID

  •  0
  • xcelm  · 技术社区  · 6 年前

    嗨,我想基于“master”类别生成非主键ID。在下面显示的我的域模型中,Lvl2 ID是基于Lvl1 ID生成的。我想我应该使用FluentAPI来实现这一点,但是我没有找到任何具体的例子。

    在数据库中应该是什么样的示例是:

    ID  CatL1Id CatL1Name CatL2Id CatL2Name
    1   1       PC        1       AllInOne
    2   1       PC        2       Classic PC
    3   2       Laptop    1       NetBook
    4   2       Laptop    2       Class Laptop
    5   3       Mac       1       MacBook Pro
    

    我的域模型是

    public class Category
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int CategoryId { get; set; }
    
        public int CategoryLevel1Id { get; set; }
    
        public int CategoryLevel2Id { get; set; }
    
        public int CategoryLevel3Id { get; set; }
    
        public string CategoryLevel1Name { get; set; }
    
        public string CategoryLevel2Name { get; set; }
    
        public string CategoryLevel3Name { get; set; }
    
        public virtual ICollection<Product> Products { get; set; }
    }
    

    感谢您的帮助!提前谢谢

    2 回复  |  直到 6 年前
        1
  •  4
  •   Tanveer Yousuf    6 年前

    您的域模型在转换为数据库表时将违反数据库规范化原则。

    问题 :category实体中的levels列将创建冗余,更不用说,如果您稍后发现需要容纳更多级别,则需要对模型进行更改。

    解决方案 :我建议您:

    步骤1。修改您的实体并创建这样的父子关系:

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    namespace DomainModel
    {
        public class Category
        {
            public Category()
            {
                Children = new HashSet<Category>();
            }
    
            public int Id { get; set; }
    
            [Required]
            public string Name { get; set; }
    
            public int? ParentId { get; set; }
    
            public virtual ICollection<Category> Children { get; set; }
    
            public virtual Category Parent { get; set; }
        }
    }
    

    父子关系允许您根据需要创建任意多个级别。如果一个类别不属于某个级别(换句话说是根类别),它的父级将为空。

    步骤2。在 OnModelCreating()。 你的方法 数据库上下文 类,按如下方式指定关系:

    modelBuilder.Entity<Category>()
        .HasMany(e => e.Children)
        .WithOptional(e => e.Parent)
        .HasForeignKey(e => e.ParentId);
    

    数据库中的结束表如下所示:

    enter image description here

        2
  •  0
  •   Sani Huttunen    6 年前

    我把那张桌子分成两张桌子。一个用于cat1,一个用于cat2,带有cat1的外键。这样,您就不会有太多重复的cat1条目,您可以轻松地将cat2映射到正确的cat1。

    这将使它成为 一对多 1类和2类之间的关系。

    我不会担心ID值到底是什么,因为这无关紧要。
    映射更重要,而且索引设置正确。

    我的想象是这样的:

    Category 1:
    ID  CategoryLevel1Name 
    1   PC
    2   Laptop
    3   Mac
    
    Category 2:
    ID  CategoryLevel1Id CategoryLevel2Name 
    1   1                AllInOne
    2   1                Classic PC
    3   2                NetBook
    4   2                Class Laptop
    5   3                MacBook Pro
    
    public class Category1
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        public string CategoryLevel1Name { get; set; }
    
        public ICollection<Category2> Category2s { get; set; }
    }
    
    public class Category2
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        public int CategoryLevel1Id { get; set; }
        public string CategoryLevel2Name { get; set; }
    
        [ForeignKey("CategoryLevel1Id ")]
        public Category1 Category1 { get; set; }
    }
    

    免责声明:代码未经测试。