VisualStudioギャラリーからダウンロードしたMicrosoftのPOCOコード生成テンプレートでEntityFramework4を使用しています。また、データベースからEFモデルを生成するときに、デフォルトのオプションである「モデルに外部キーを含める」を選択したままにします。
私はこの問題を非常に単純なモデルで再現することができました。オプションの1対多の関係にある2つのテーブル/クラスのみです。この場合、私は住所と人を使用しています。個人は1つまたはゼロのアドレスを持つことができ、アドレスはゼロから多数の人々を持つことができます。
テーブルは次のようになります。
CREATE TABLE [dbo].[Person](
[PersonID] [uniqueidentifier] NOT NULL,
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[AddressID] [uniqueidentifier] NULL,
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED ([PersonID] ASC )
CREATE TABLE [dbo].[Address](
[AddressID] [uniqueidentifier] NOT NULL,
[Street1] [nvarchar](50) NOT NULL,
[Street2] [nvarchar](50) NULL,
[City] [nvarchar](50) NOT NULL,
[State] [char](2) NOT NULL,
[Country] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Address] PRIMARY KEY CLUSTERED ([AddressID] ASC)
ALTER TABLE [dbo].[Person] WITH CHECK ADD CONSTRAINT [FK_Person_Address]
FOREIGN KEY([AddressID])
REFERENCES [dbo].[Address] ([AddressID])
Addressオブジェクトを作成し、それをデータベースから取得した既存のPersonオブジェクトに追加しようとすると、null参照例外が発生します。
TestPOCOEntities ctx = new TestPOCOEntities();
var person = ctx.People.FirstOrDefault(p => p.PersonID == new Guid("58AD37B4-1EBE-4649-940C-A141732C9901"));
var addr = new Address {AddressID = Guid.NewGuid(), Street1 = "123 Main St"};
person.Address = addr; // This line throws the exception
ctx.SaveChanges();
コールスタックを掘り下げてみると、例外は私のコードやテンプレートで生成されたコードからではなく、AddressID
セッターのPersonクラスのランタイム動的プロキシ内でスローされています。(具体的には、System.Data.Objects.EntityEntry.FixupEntityReferenceByForeignKey(EntityReference reference)
メソッド。)
POCOテンプレートの代わりにデフォルトのEFコード生成を使用した場合、この例外は発生しません。POCOテンプレートを使用しても発生しませんが、データベースからモデルを生成するときに[モデルに外部キーを含める]チェックボックスをオフにします。
以下を追加すると、エラーが消える可能性があります。
var addr = new Address {AddressID = Guid.NewGuid(), Street1 = "123 Main St"};
ctx.Addresses.AddObject(addr); // Adding this line...
person.Address = addr; // Means no more exception here!
POCOテンプレートを使用し、モデルに外部キーを含めることの組み合わせで、永続オブジェクトを操作するときにこの種のコード変更が必要になる理由がわかりません。これは既知のバグですか?私は何かが足りないのですか?これは何らかの理由で設計によるものですか?