【Entity Framework】聊聊EF中键

简介: 【Entity Framework】聊聊EF中键

一、概述

键用作每个实体实例的唯一标识符。EF中的大多数实体都有一个键,该键映射到关系数据库中主键的概念(对于没有键的实体,后面会讲解无键实体)。实体可以有出了主键之外的其他键。


二、配置主键

2.1 约定配置主键

根据约定,名为IdId的属性将被配置为实体的主键。

public class User
{
    //主键
    public long Id{get;set;}
    public string Name{get;set;}
    public string EnName{get;set;}
}

public class Address
{
    //主键
    public long AddressId{get;set;}
    public string AddressName{get;set;}
    public string Linkman{get;set;}
    public string phone{get;set;}
}

从属实体类型使用不同的规则来定义键

2.2 单个属性配置为实体主键

可将单个属性配置为实体的主键

  • 数据注释
public class User
{
    // key 注释定义关键字
    [Key]
    public long UUId{get;set;}
    public string Name{get;set;}
    public string EnName{get;set;}
}
  • Fluent API
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>()
        .HasKey(c => c.UUId);
}

2.3 组合主键

可以将多个属性配置为实体的键及组合键。约定仅在特定情况下设置复合键。

EF Core 7.0中引入了[PrimaryKey]属性。在旧版本中使用Fluent API

  • 数据注释
[PrimaryKey(nameof(Phone),nameof(UserCode))]
public class User
{
    public string Phone{get;set;}
    public string UserCode{get;set;}
    public string Address{get;set;}
}
  • Flument API
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>().HasKey(c=>new{c.Phone,c.UserCode});
}


三、主键名称

根据约定,在关系数据库上,主键使用名称PK_进行创建。可按如下方式配置主键约束的名称:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>()
        .HasKey(b => b.UserId)
        .HasName("PrimaryKey_UserId");
}


四、键类型和值

虽然EF Core支持使用任何基元类型的属性作为主键(包括string,guid,byte[]等),但并非所有数据库都支持所有类型作为键。在某些情况下,键值可以自动转换为支持的类型,否则应手动指定转换。


向上下文添加新实体时,键属性必须始终具有非默认值,但某些类型将由数据库生成。在这种情况下,当添加实体以用于跟踪时,EF将尝试生成一个临时值。调用SaveChanges后,临时值将替换为数据库生成的值。


如果键属性的值由数据库生成,并且在添加实体时指定了非默认值,则 EF 将假定该实体已存在于数据库中,并尝试更新它,而不是插入新的实体。 若要避免这种情况,请禁用值生成


五、备用键

除主键外,备选键还充当每个实体实例的备用唯一标识符;它可以用作关系的目标。使用关系数据库时,它会映射到备选键列上的唯一索引/约束的感念以及引用该列的一个或多个外键约束。


如果只想对列强制执行唯一性,请定义唯一索引而不是备选建。在EF中,备选建是只读的,并且提供对唯一索引的其他语义,因为他们可以用作外键的目标。

备选建通常根据需要引入,无需手动配置。根据约定,当你将不是主键的属性标识为关系的目标时,会引入备选键。

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; }
}
public class GoyeerContext : 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);
    }
}

还可将单个属性配置为备选建:

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");
}
目录
相关文章
|
6月前
|
开发框架 缓存 .NET
【Entity Framework】EF中DbSet类详解
【Entity Framework】EF中DbSet类详解
114 1
【Entity Framework】EF中DbSet类详解
|
6月前
|
存储 SQL 开发框架
【Entity Framework】如何使用EF中的生成值
【Entity Framework】如何使用EF中的生成值
51 0
|
6月前
|
SQL 开发框架 .NET
【Entity Framework】聊聊EF中复杂查询运算符
【Entity Framework】聊聊EF中复杂查询运算符
138 0
|
6月前
|
存储 SQL API
【Entity Framework】EF中实体属性
【Entity Framework】EF中实体属性
61 0
|
6月前
|
SQL 开发框架 缓存
【Entity Framework】 EF中DbContext类详解
【Entity Framework】 EF中DbContext类详解
218 0
|
6月前
|
存储 SQL 开发框架
【Entity Framework】你要知道EF中功能序列与值转换
【Entity Framework】你要知道EF中功能序列与值转换
45 0
|
6月前
|
SQL API 数据库
【Entity Framework】EF配置文件设置详解
【Entity Framework】EF配置文件设置详解
66 0
|
6月前
|
SQL 数据库
【Entity Framework】如何理解EF中的级联删除
【Entity Framework】如何理解EF中的级联删除
62 0
|
6月前
|
SQL 数据库连接 数据库
【Entity Framework】EF连接字符串和模型
【Entity Framework】EF连接字符串和模型
47 0
|
6月前
|
SQL 存储 开发框架
【Entity Framework】EF中的增删改查
【Entity Framework】EF中的增删改查
170 0