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

时间:2019-01-19 12:51:04

标签: c# entity-framework

您好,我想根据“主”类别生成非主键ID。在下面显示的我的域模型中,将根据lvl1 ID生成lvl2 ID。我想我应该使用流畅的API来做到这一点,但是我还没有找到任何具体的例子。

在数据库中应显示为以下示例:

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 个答案:

答案 0 :(得分:4)

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

问题:类别实体中的“级别”列将创建冗余,并且如果您以后发现要容纳更多级别,则无需更改模型。

解决方案:这是我对您的建议:

第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; }
    }
}

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

步骤2。在 DbContext 类的 OnModelCreating()方法中,指定如下关系:

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

数据库中的终端表如下:

enter image description here

答案 1 :(得分:0)

我将该表拆分为两个表。一个用于Cat1,一个用于Cat2,带有Cat1的外键。这样,您就不会有很多重复的Cat1条目,并且可以轻松地将Cat2映射到正确的Cat1。

这将使Cat1和Cat2之间成为一对多关系。

我不担心确切的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; }
}

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