EF Core处理备用主键

时间:2019-02-27 10:11:39

标签: entity-framework-core ef-database-first

我有一些使用dotnet ef dbContext scaffold构建的EF Core模型,以使用数据库优先方法生成模型。我的问题是数据库使用整数主键,用于将表链接在一起,但是具有基于字符串的索引,该索引将用作搜索表的健全索引。

但是:当我尝试使用FindAsync("abc000")时,我得到了完全预期的错误The key value at position 0 of the call to 'DbSet<Entity>.Find' was of type 'string', which does not match the property type of 'long'.

因此,有两个问题:

  1. EF如何确定主键是什么?
  2. 有什么办法可以重新调整它,以便可以使用“查找”按名称搜索实体,但保留自动增量主键吗?
  3. 我是不是很喜欢自动增量整数键作为连接表的字段?

它们看起来像这样:

class Entity
{
    long Id;
    string Key;
};

在OnModelCreating中:

modelBuilder.Entity<Entity>(entity =>
{
    entity.ToTable("tb_entity", "main");

     entity.HasIndex(e => e.Key)
           .HasName("uq_entity_key")
           .IsUnique();

    entity.Property(e => e.Id).HasColumnName("_id");

    entity.Property(e => e.Key)
          .HasColumnName("key")
          .HasMaxLength(255);
}

创建表的SQL如下:

CREATE TABLE [tb_entity]
(
    _id BIGINT PRIMARY KEY IDENTITY(1,1),
    key NVARCHAR(255) CONSTRAINT uq_entity_key UNIQUE NOT NULL,
);

1 个答案:

答案 0 :(得分:4)

  
      
  1. EF如何确定主键是什么?
  2.   

如果未通过[Key]属性或HasKey流利的API明确指定,则由convention来指定:

  

按照惯例,名为Id<type name>Id的属性将被配置为实体的键。

您可以通过查看查看该信息

var pk = context.Model.FindEntityType(typeof(Entity)).FindPrimaryKey();
  
      
  1. 有什么办法可以重新调整它,以便可以使用“查找”按名称搜索实体,但保留自动增量主键吗?
  2.   

您可以使用Entity的PK为Name的数据注释/流利的API来说谎EF Core,但我不建议这样做,因为这会导致FK关系的错误假设,并且通常是不好的。

相反,只需不使用专用于PK的Find / FindAsync方法。 FirstFirstOrDefaultSingleSingleOrDefault(以及它们的Async对应对象)允许您按任何条件(例如,而不是FindAsync("abc000"),您可以使用FirstOrDefaultAsync(e => e.Name == "abc000")

唯一的区别是Find方法首先在本地缓存中搜索,这在大多数使用情况下没有太大的好处。另一方面,Find方法不支持预先加载,而后面的方法则支持。后者针对数据库执行,并且由于该列上具有唯一索引,因此它们应具有足够的性能。

  
      
  1. 我是不是很喜欢自动增量整数键作为连接表的字段?
  2.   

这是非常标准的数据库设计,通常比自然PK更可取,我认为没有任何问题。