【问题标题】:Can we have table without primary key in entity framework?我们可以在实体框架中拥有没有主键的表吗?
【发布时间】:2013-03-13 09:22:55
【问题描述】:

我刚刚在msdn练习code first新数据库实体框架,我想知道code first新数据库EF中是否可以创建没有主键的表?

【问题讨论】:

标签: c# entity-framework


【解决方案1】:

EF 可以对数据库执行的操作与使用数据库可以执行的操作之间存在很大差异。

大多数数据库允许一个表没有主键。 大多数数据库还允许一个表没有聚集索引/索引组织表(或者它的具体术语)它在其他数据库系统中)。

这并没有错,也不应该说没有 PK 的表是个坏主意。

与往常一样,这取决于特定表的需求和使用情况。例如一个日志表,不需要PK。它永远不会被用作FK,那它有什么用呢?

底线,EF 不支持没有键的表 开箱即用,有一些奇怪的解决方法,但我所见过的都不够好。真可惜。

【讨论】:

  • 没错。我们有一个带有一条记录的设置表。真的不需要PK。
  • 我有一个程序不是由另一家公司制作的,因此我无法更改,但它有一个没有主键的表,它包含订单的订单行。通过使用 articleID(或者可能是行号)和 orderID 组合的两列来更新或删除单个行,添加新行没有问题。这是它似乎被使用的一种方式。并不是说这是一个好主意还是坏主意,只是一个现实生活中的例子,如果我想与 EF 连接到同一个数据库,我必须处理一些事情。
  • “不应该说没有 PK 的表是个坏主意”。在没有 PK 的情况下创建表确实是一个好主意。我认为它应该是创建表时的默认选项,如果不是 FK,谁需要 PK,对吧?
【解决方案2】:

不,你不能,因为当你进行更新或删除操作时,Entity Framework 需要知道密钥来跟踪对象。

无论如何,没有 PrimaryKey 的表不是一个好主意

【讨论】:

  • 好吧 wahid,你是对的,没有 PK 的表,无法执行更新或删除等一般操作,但如果我可以告诉 EF 使用唯一但不是 PK 的特定列,那么在这种情况下,这个操作(更新,删除)可以由 EF 执行吗?
  • 没有列应该是PK
  • @WahidBitar 如果我只有复合键而不是表中的任何其他键怎么办?
  • @MoxShah 是的,我想你会在 EF 核心中拥有它。可悲的是,我不知道为什么在某些情况下它不接受仅包含组合键的表。正如我所尝试的,如果该表是多对多关系的一部分,它将起作用,但是当您有一个没有这种关系的表时,它在您添加独立主键之前将不起作用。
  • @WahidBitar 感谢您的回复 Wahid,非常感谢,现在我已经添加了独立的主键。
【解决方案3】:
  1. 实体框架必须在为表建模的实体(POCO 类)上标识一个键。
  2. 您在 Entity Framework 中定义的键需要存在于底层数据库(例如 sql 表)中。

如果您的 SQL 表没有主键,您仍然可以在实体框架中对其进行建模,您只需为该实体定义一个键。选择实体上的一个或多个(可能是所有)列,当它们组合时,将在实体集合中唯一标识该实例。请注意,这仅对更新或删除实体很重要,因为它们需要针对该集合中的其他实体进行唯一标识以针对更改。查找/选择和添加/插入不需要这种一致性。

【讨论】:

  • 但它根本不允许我添加表格
  • @dangalg 是的,实体框架可以推断出一个键,它适用于选择。但是如果你需要插入、更新或删除数据,那么你需要一个数据库中的主键。
【解决方案4】:

有时添加 PK 是不可能的,因为它可以是只读的、您必须使用的客户端的超级保护数据库。 EF 即使在 SELECT 操作上也会引发异常。当我遇到这个问题时,我能够像这样解决它(名称是人为的):

[Table( "WeirdTable", Schema = "SomeSchema" )]
public class WeirdTable
{
    [Column( "ID1" )]
    public int Id1 { get; set; }

    [Column( "ID2" )]
    public int Id2 { get; set; }
}

在上下文的代码文件中:

protected override void OnModelCreating( DbModelBuilder model_builder )
{
    base.OnModelCreating( model_builder );
    model_builder.Entity<WeirdTable>().HasKey(
        t => new { t.Id1, t.Id2 }
    );
}

所以基本上你只需要指定哪些列可以是主键。

【讨论】:

    【解决方案5】:

    从 .NET Core 2.1 开始,EF Core 支持没有主键的模型。
    这是通过查询类型而不是实体类型的概念来实现的。
    https://docs.microsoft.com/en-us/ef/core/modeling/query-types

    查询类型的一些主要使用场景是:

    • 用作即席 FromSql() 查询的返回类型。
    • 映射到数据库视图。
    • 映射到未定义主键的表。
    • 映射到模型中定义的查询。

    查询类型有限制。它们不能在数据库中插入、更新或删除。而且它们对导航属性的支持有限。

    【讨论】:

    • 所以,我有一个问题。当我们将查询类型映射到表时。该表被视为只读,我们不能对其进行 CRUD,那么我们如何用数据填充该表?在首次运行应用程序时,我们必须如何填写该表?!!
    【解决方案6】:

    EF.Core 5 将具有 [Keyless] 属性,允许拥有没有 PK 的实体。 但它仍在开发中。

    EF.Core 5 what's new

    【讨论】:

    猜你喜欢
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多