【发布时间】:2013-03-13 09:22:55
【问题描述】:
我刚刚在msdn练习code first新数据库实体框架,我想知道code first新数据库EF中是否可以创建没有主键的表?
【问题讨论】:
标签: c# entity-framework
我刚刚在msdn练习code first新数据库实体框架,我想知道code first新数据库EF中是否可以创建没有主键的表?
【问题讨论】:
标签: c# entity-framework
EF 可以对数据库执行的操作与使用数据库可以执行的操作之间存在很大差异。
大多数数据库允许一个表没有主键。 大多数数据库还允许一个表没有聚集索引/索引组织表(或者它的具体术语)它在其他数据库系统中)。
这并没有错,也不应该说没有 PK 的表是个坏主意。
与往常一样,这取决于特定表的需求和使用情况。例如一个日志表,不需要PK。它永远不会被用作FK,那它有什么用呢?
底线,EF 不支持没有键的表 开箱即用,有一些奇怪的解决方法,但我所见过的都不够好。真可惜。
【讨论】:
不,你不能,因为当你进行更新或删除操作时,Entity Framework 需要知道密钥来跟踪对象。
无论如何,没有 PrimaryKey 的表不是一个好主意
【讨论】:
如果您的 SQL 表没有主键,您仍然可以在实体框架中对其进行建模,您只需为该实体定义一个键。选择实体上的一个或多个(可能是所有)列,当它们组合时,将在实体集合中唯一标识该实例。请注意,这仅对更新或删除实体很重要,因为它们需要针对该集合中的其他实体进行唯一标识以针对更改。查找/选择和添加/插入不需要这种一致性。
【讨论】:
有时添加 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 }
);
}
所以基本上你只需要指定哪些列可以是主键。
【讨论】:
从 .NET Core 2.1 开始,EF Core 支持没有主键的模型。
这是通过查询类型而不是实体类型的概念来实现的。
见https://docs.microsoft.com/en-us/ef/core/modeling/query-types
查询类型的一些主要使用场景是:
- 用作即席 FromSql() 查询的返回类型。
- 映射到数据库视图。
- 映射到未定义主键的表。
- 映射到模型中定义的查询。
查询类型有限制。它们不能在数据库中插入、更新或删除。而且它们对导航属性的支持有限。
【讨论】:
EF.Core 5 将具有 [Keyless] 属性,允许拥有没有 PK 的实体。
但它仍在开发中。
【讨论】: