zoukankan      html  css  js  c++  java
  • Entity Framework Core

      键充当每个实体实例(对应数据库表中的一条记录)的唯一标识符。

      EF中大多数实体都要一个键,此键映射到关系型数据库中‘主键’的概念。

      实体还可以有超过主键的其他键——备用键。

      1、约定:默认将名为Id或名为<type name>Id的属性配置为实体的主键:

    class Car
    {
        public string Id { get; set; }
    
        public string Make { get; set; }
        public string Model { get; set; }
    }
    
    class Truck
    {
        public string TruckId { get; set; }
    
        public string Make { get; set; }
        public string Model { get; set; }
    }

      2、可以将单个属性配置为实体的主键:

    class Car
    {
        [Key]
        public string LicensePlate { get; set; }
    
        public string Make { get; set; }
        public string Model { get; set; }
    }

      3、还可以将多个属性配置为主键(联合主键,或者叫组合键)。组合键的关键是确认复合秘钥(下文中的new { 属性1,  属性2 }),只能使用Fluent API进行配置。不会默认配置组合键,且不能通过数据批注来配置:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Car>()
            .HasKey(c => new { c.State, c.LicensePlate });
    }

    主键名称

      约定:对于关系型数据库,使用属性名创建主键的名称为 PK_<type name>。当然,也可以通过Fluent API的方式自定义配置主键约束名:

    modelBuilder.Entity<PostModel>().HasKey(c => new { c.Title, c.Content }).HasName("PrimaryKey_Title_Content");

    键类型和值

      尽管EF Core 支持使用任何基元类型的属性作为主键(包括 string 、 Guid 、byte[]和其他类型),但并不是所有数据库都支持将所有类型作为键。 在某些情况下,可以自动将键值转换为支持的类型,否则应 手动指定转换。

      在DbContext中添加实体时,键属性必须没有默认值,但某些类型将由数据库生成。这种情况下,当对实体进行追踪时,EF会尝试生成一个临时值,在调用SaveChanges方法后,临时值将被替换为数据库生成的值。

      重要:如果某个键属性的值由数据库生成(比如SQL Server中的自增列IDENTITY属性),而在添加实体时指定了一个非默认值,则 EF 将假定该实体在数据库中已存在,并且将尝试对其进行更新而不是插入一个新的值。 若要避免这种情况,请禁用值生成或了解 如何为生成的属性指定显式值

    备用键

      除了主键,备用键还可用作每个实体实例的唯一标识符的替代(备用)。它可以作为一种关系的目标。在使用关系数据库时,这将映射到备用键列上的唯一索引/约束和引用该列的一个或多个外键约束的概念。

      注意:如果只希望对列强制唯一性,则定义唯一索引而不是备用键(请参阅索引)。在EF中,备用键是只读的,并且在唯一索引上提供额外的语义,因为它们可以用作外键的目标。

      

      备用键通常在需要时为您引入,您不需要手动配置它们。按照惯例,当您将一个不是主键的属性标识为关系的目标时,将为您引入一个备用键:

    class MyContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Post>()
                .HasOne(p => p.Blog)
                .WithMany(b => b.Posts)
                .HasForeignKey(p => p.BlogUrl)
                .HasPrincipalKey(b => b.Url);
        }
    }
    
    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
    
        public List<Post> Posts { get; set; }
    }
    
    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
    
        public string BlogUrl { get; set; }
        public Blog Blog { get; set; }
    }

      也可以配置一个属性作为一个备用键::

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Car>()
            .HasAlternateKey(c => c.LicensePlate);
    }

      您还可以将多个属性配置为备用键(称为复合备用键):

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Car>()
            .HasAlternateKey(c => new { c.State, c.LicensePlate });
    }

      最后,按照约定,为备用键引入的索引和约束将被命名为AK_<类型名>_<属性名>(对于复合备用键<属性名>将成为一个下划线分隔的属性名列表)。你可以配置备用键的索引和唯一约束的名称:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Car>()
            .HasAlternateKey(c => c.LicensePlate)
            .HasName("AlternateKey_LicensePlate");
    }
  • 相关阅读:
    实例15_C语言绘制万年历
    医生酒精
    实例13_求解二维数组的最大元素和最小元素
    用二维数组实现矩阵转置
    C语言中的typedef跟define的区别
    C语言设计ATM存取款界面
    MyBatis,动态传入表名,字段名的解决办法
    在mybatis执行SQL语句之前进行拦击处理
    使用Eclipse构建Maven的SpringMVC项目
    Debug过程中的mock (及display窗口的使用)
  • 原文地址:https://www.cnblogs.com/hiwuchong/p/14141801.html
Copyright © 2011-2022 走看看