4

EF Code Firstでは、次のようにコーディングすることで 1 対 1 の関係を作成できます。

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 データベースを使用して同じ関係を作成しようとしたときに、問題が発生しました。これが私のコードです:

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 との 1 対 1 の関係を行うのは難しいことも知っています。また、不可能だと言う人もいます。誰でも私に何か提案をしてもらえますか? ありがとうございました。

更新:私のケースを明確にするために、Visual Studio 2012 データベース プロジェクトでデータベースを設計し、それを SQL サーバーに公開し、その後、SQL サーバーのデータベースから .edmx ファイルを作成/更新しようとしています。EF が正しく認識できる 1 対 1 の関係を作成し、.edmx ファイルに適切なクラスを作成する方法がわかりません。

4

3 に答える 3

7

1 対 1 の関係を構築することは、特に一般的な要件ではありませんが、それほどトリッキーではなく、もちろん不可能でもありません。この場合、なぜそれを望むのかわかりません。人々がこれを言っているなら、あなたは間違った人々と話している.

とにかく、あなたがそうであるように SQL クエリを使用することは EF とは関係ありません。データベースを直接操作しているだけです。最初の CREATE では、制約を追加しようとしていますが、まだ他のテーブルを作成していません...あなたはあなたの質問で言及しました。

最初に両方のテーブルを作成してから、ALTER TABLE で制約を追加する必要があると思います。

さらに、SO で 1:1 に関する質問を検索すると、かなり多くの情報が表示されるので、そうすることをお勧めします。

EDIT:データベースプロジェクトを使用して(私はVS Expressしか持っていないので、それらを持っていません)、SQLを使用して「1:1」の関係を作成し、参照する(おそらく異なる)プロジェクトにエンティティデータモデルを追加しますデータベースと自動的に 1:1 の関係を作成しますか?

残念ながら、それはまったく別の話です。私が 1:1 を作成する可能性について話していたとき、それはデータベース自体ではなく EF のみを参照していました。あなたがSQLで1:1を作成すると言ったように、実際には非常に困難/不可能です。1:1 の関係に挿入するには、両方のテーブルにまったく同時に挿入するか、行を追加するときに制約を一時的に無効にしていじる必要があるのは理にかなっていると思います。

一般に、いくつかの異なるオプションがあります。

  1. 不必要にテーブルを分割しないでください。真の 1:1 ではすべてのデータが必要なので、分割する唯一の理由はパフォーマンス上の理由 (パーティショニングなど) のためであり、この場合は避けます。

  2. ここに示すように、複数のテーブルを単一のエンティティにマップします。

  3. 1:0..1 の関係を作成し、アプリケーションで独自の要件を適用します。

オプション 2 または 3 のいずれかで、次の SQL を使用して、リレーションシップの FK と同じ PK を 2 番目のテーブルで使用するリレーションシップを作成できます。

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 
);

可能な場合は、ストアで生成された ID も使用することをお勧めします。

于 2013-06-23T08:37:45.303 に答える
2

UserDetailテーブルからUserDetailIDを削除し、 UserIDをUserテーブルのUserID列の主キーと外部キーの両方にします。

これは、データベースで 1 対 1 の関係を作成する正しい方法であり、EF はそれを認識し、データベース ファーストのアプローチでエンティティを適切にマップします。

于 2016-06-06T11:19:17.710 に答える