【问题标题】:Create one to one relationship by using entity framework database first首先使用实体​​框架数据库创建一对一的关系
【发布时间】:2013-06-22 20:48:57
【问题描述】:

EF Code First中,我们可以通过这样的编码来创建一对一的关系:

public class User
{
public int UserID {get;set;}
public string Name {get;set;}
public int UserDetailID {get;set;}

public UserDetail Detail {get;set;}
}

public class UserDetail
{
public int UserDetailID {get;set;}
public string Address {get;set:}
public int UserID {get;set;}

public User User {get;set;}

}

但是,当我尝试在 Visual Studio 2012 中使用 EF Database first 创建相同的关系时,我遇到了麻烦。这是我的代码:

CREATE TABLE [dbo].[Users] (
[UserID]                 UNIQUEIDENTIFIER CONSTRAINT [DF_Users_UserID] DEFAULT (newid()) NOT NULL,
[UserDetailID]                 UNIQUEIDENTIFIER NOT NULL,
[Name]                      NVARCHAR (50)    NOT NULL,
CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ([UserID] ASC),
CONSTRAINT [FK_Users_UserDetails] FOREIGN KEY ([UserDetailID]) REFERENCES [UserDetails]([UserDetailID])
);

CREATE TABLE [dbo].UserDetails] (
[UserDetailID]     UNIQUEIDENTIFIER CONSTRAINT [DF_UserDetails_UserDetailID] DEFAULT (newid()) NOT NULL,
[UserID]           UNIQUEIDENTIFIER NOT NULL,
[Address]             NVARCHAR(100) NOT NULL,
CONSTRAINT [PK_UserDetails] PRIMARY KEY CLUSTERED ([UserDetailID] ASC),
CONSTRAINT [FK_UserDetails_Users] FOREIGN KEY ([UserID]) REFERENCES [dbo].[Users] ([UserID])

错误信息类似于

"Error  2   SQL01767: Foreign key 'FK_Users_UserDetails' references invalid table 'UserDetails'.    

我认为这个错误的原因可能是当它试图引用外键“UserDetailID”时,它发现它还没有被创建。但是我不知道如何解决这个问题,我什至不知道这是解决问题的方法,我知道与 EF 建立一对一的关系很棘手,或者有些人甚至说这是不可能的。谁能给我任何建议?谢谢。

更新:为了澄清我的情况,我正在尝试在 Visual Studio 2012 数据库项目中设计数据库,然后将其发布到 SQL 服务器,然后从 SQL 中的数据库创建/更新我的 .edmx 文件服务器。我不确定如何创建 EF 可以正确识别的一对一关系并在 .edmx 文件中创建正确的类。

【问题讨论】:

  • 你的意思是使用EF Model First,因为当你已经有一个数据库时使用Database First?
  • 您需要在尝试插入外键之前制作两个表。
  • @Sniffer 请查看我的更新。谢谢。
  • 你不应该使用数据库优先,你应该使用模型优先,它是专门为这些情况而设计的。

标签: entity-framework ef-code-first one-to-one ef-database-first


【解决方案1】:

创建 1:1 关系并不是那么棘手,当然也不是不可能,尽管这不是一个特别常见的要求,在这种情况下,我看不出你为什么想要它?如果人们这样说,那么你是在和错误的人交谈。

无论如何,使用 SQL 查询似乎与 EF 无关,您只是直接使用数据库,在第一个 CREATE 中,您尝试添加约束,但尚未创建另一个表。 ..正如你在问题中提到的那样。

我认为您需要先创建两个表,然后使用 ALTER TABLE 添加约束。

另外在 SO 上搜索有关 1:1 的问题会出现很多问题,所以我建议你这样做。

编辑:所以使用数据库项目(我只有 VS Express,所以我没有那些)你想使用 SQL 创建一个“1:1”关系,然后将一个实体数据模型添加到一个(可能不同)引用数据库并自动创建1:1关系的项目?

不幸的是,这是一个完全不同的故事。当我谈论创建仅参考 EF 而不是数据库本身的 1:1 的可能性时。正如您所说,在 SQL 中创建 1:1 实际上非常困难/不可能。我认为这是有道理的,为了插入 1:1 关系,您需要以某种方式同时插入两个表,或者在添加行时短暂地摆弄禁用约束。

一般有几种不同的选择。

  1. 不要不必要地拆分表。在真正的 1:1 中,所有数据都是必需的,因此拆分的唯一原因是出于性能原因(例如 partioning),在这种情况下我会避免这样做。

  2. 将多个表映射到单个实体,如显示here

  3. 创建 1:0..1 关系并在应用程序中强制执行您自己的要求。

在选项 2 或 3 中,您可以使用以下 SQL 创建关系,该关系在第二个表上使用与关系中的 FK 相同的 PK。

CREATE TABLE [dbo].[Users] (
[UserID] UNIQUEIDENTIFIER CONSTRAINT [DF_Users_UserID] DEFAULT (newid()) NOT NULL,
[Name] NVARCHAR (50)    NOT NULL,
CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ([UserID] ASC),
);

CREATE TABLE [dbo].[UserDetails] (
[UserID]           UNIQUEIDENTIFIER NOT NULL,
[Address]             NVARCHAR(100) NOT NULL,
CONSTRAINT [PK_UserDetails] PRIMARY KEY CLUSTERED ([UserID] ASC),
CONSTRAINT [FK_UserDetails_Users] FOREIGN KEY ([UserID]) REFERENCES [dbo].[Users] ([UserID]) ON DELETE CASCADE 
);

我建议您也尽可能使用商店生成的身份。

【讨论】:

  • 谢谢戴夫。一个后续问题是,如何先创建没有约束的表,然后在 Visual Studio 2012 数据库项目中添加约束?
  • 很容易创建表,然后使用 ALTER TABLE 添加约束,您可以在 SO、MSDN 或任何地方找到有关信息。但是我不认为它会帮助你......查看更新的答案。
  • 谢谢你,你明白我的意思,我以为我仍然有问题......我想投票赞成你的答案,但不幸的是我没有足够的声誉。再次感谢您。
  • 我不得不重新阅读此答案以确定您确实提供了答案(当我发现这一行时,我最初停止阅读“这实际上非常困难/不可能,正如您所说的那样,在SQL').. 这太冗长了.. 你为什么要离开你误解问题的部分(这几乎是一开始的评论)?
【解决方案2】:

只需从 UserDetail 表中删除 UserDetailID 并将 UserID 设为 UserID 的主键和外键> User 表的列。

这是在数据库中建立 1:1 关系的正确方法,EF 识别它并使用数据库优先方法适当地映射实体。

【讨论】:

    【解决方案3】:

    这个问题是几年前的......并且没有说明 ef 版本......但一个答案是从两个表中删除 UserDetailIDUserID 应该是两个表上唯一的主键。

    'unqieidentifier' (GUID) 数据类型不应该造成问题(与使用 INT 相对),但您当然不想用 newId 填充它。

    【讨论】:

      猜你喜欢
      • 2011-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多