4

私は非常に大きなプロジェクトをコーディングしていましたが、EF4とジョイナテーブルの操作に問題がありました。Entity Framework 4 - ジョイナテーブルを使用してレコードを挿入する方法C#

私たちは、次のSQLテーブルdefintionsがあるとします。

CREATE TABLE [dbo].[SQLEntity](
    [Id] [bigint] IDENTITY(1,1) NOT NULL, 
    [Field1] [nvarchar](128) NOT NULL, 
    [Field2] [nvarchar] (256), 
    [DateAdded] [datetime] NOT NULL, 
    CONSTRAINT [PK_SQLEntity] PRIMARY KEY CLUSTERED ( 
     [Id] ASC 
    ) WITH (
     PAD_INDEX = OFF, 
     STATISTICS_NORECOMPUTE = OFF, 
     IGNORE_DUP_KEY = OFF, 
     ALLOW_ROW_LOCKS = ON, 
     ALLOW_PAGE_LOCKS = ON 
    ) ON [PRIMARY] 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 
GO 

CREATE TABLE [dbo].[Util_LookupValues](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [Description] [nvarchar](64) NOT NULL, 
    CONSTRAINT [PK_Util_LookupValues] PRIMARY KEY CLUSTERED (
     [Id] ASC 
    )WITH (
     PAD_INDEX = OFF, 
     STATISTICS_NORECOMPUTE = OFF, 
     IGNORE_DUP_KEY = OFF, 
     ALLOW_ROW_LOCKS = ON, 
     ALLOW_PAGE_LOCKS = ON 
    ) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

CREATE TABLE [dbo].[Xref_EntityValues](
    [SQLEntityId] [bigint] NOT NULL, 
    [LookupId] [int] NOT NULL, 
    CONSTRAINT [PK_Xref_PositionBenefits] PRIMARY KEY CLUSTERED (
     [SQLEntityId] ASC, 
     [LookupId] ASC 
    )WITH (
     PAD_INDEX = OFF, 
     STATISTICS_NORECOMPUTE = OFF, 
     IGNORE_DUP_KEY = OFF, 
     ALLOW_ROW_LOCKS = ON, 
     ALLOW_PAGE_LOCKS = ON 
    ) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[Xref_EntityValues] WITH CHECK ADD CONSTRAINT [FK_Xref_EntityValues_Entity] FOREIGN KEY([SQLEntityId]) 
REFERENCES [dbo].[SQLEntity] ([Id]) 
GO 

ALTER TABLE [dbo].[Xref_EntityValues] CHECK CONSTRAINT [FK_Xref_EntityValues_Entity] 
GO 

ALTER TABLE [dbo].[Xref_EntityValues] WITH CHECK ADD CONSTRAINT [FK_Xref_EntityValues_Util_LookupValues] FOREIGN KEY([LookupId]) 
REFERENCES [dbo].[Util_LookupValues] ([Id]) 
GO 

ALTER TABLE [dbo].[Xref_EntityValues] CHECK CONSTRAINT [FK_Xref_EntityValues_Util_LookupValues] 
GO 

ドメインモデルを使用すると、2つのエンティティで終わるだろうこれらのテーブルに基づいてcratedされたら: SqlEntityとUtil_LookupValues。

この時点で、Util_LookupValuesは値がルックアップのためにのみ定義されているテーブルです! Xref_EntityValuesは、Entityオブジェクトをルックアップ値に結びつけるジョイナーテーブルであり、ルックアップテーブルの "ルックアップ"機能を維持しながら、両者の間の人間関係を維持することができます。

Util_LookupValues内容

Id Description 
--- ------------ 
1 Person 
2 Car 

変更がドメインモデルに追加されていない場合(この質問の目的はDataEntitiesそれを呼び出すためにできます)は、その後、そのPK 1と2となるUtil_LookupValuesオブジェクトとSQLEntityを拘束します以下のように行う:

IEnumerable<Util_LookupValues> lookupValues = DataEntities.Util_LookupValues.Where(lv => lv.Id == 1 || lv.Id == 2); 

SQLEntity entity = new SQLEntity(); 
entity.Field1 = "some field"; 
entity.Field2 = "another field"; 
entity.DateAdded = DateTime.Now; 

foreach(Util_LookupValues val in lookupValues) 
{ 
    entity.Util_LookupValues.Add(val);  
} 

DataEntities.SQLEntities.Add(entity); 
DataEntities.SaveChanges(); 

問題は、しかしだけでなくXref_EntityValuesに値を追加することで、このコードは、新しいキーでUtil_LookupValuesに1と2のコピーを追加するということです!次のように 結果のデータベースは次のとおりです。

SQL Entity: 
Id Field1  Field2   DateAdded 
-- -------  ------   ---------- 
1 some field another field 04/04/2012 

Xref_EntityValues: 
SQLEntityId LookupId 
----------- --------- 
1    3 
1    4 

and Util_LookupValues: 
Id Description 
--- ------------ 
1 Person 
2 Car 
3 Person 
4 Car 

Util_LookupValuesが唯一の2元レコードとXref_EntityValuesを持って、私はそれを作るにはどうすればよいことに適切な外部キーを持っていますか?

Xref_EntityValues: 
SQLEntityId LookupId 
----------- --------- 
1    1 
1    2 

Util_LookupValues: 
Id Description 
--- ------------ 
1 Person 
2 Car 
+0

私は、SQLにどれだけの変更を加えることができるかについて幾分制約があると言いました。このコードはSilverlight 4プロジェクトで使用されるため、ドメインモデルを変更するには、すべてのWCF RIAサービスと非常に大きなコードベースを変更する必要があります。 – bleepzter

答えて

3

このラインは...

IEnumerable<Util_LookupValues> lookupValues = DataEntities.Util_LookupValues 
    .Where(lv => lv.Id == 1 || lv.Id == 2); 

...と、この行...

DataEntities.SQLEntities.Add(entity); 

... DataEntitiesコンテキストの同じインスタンスを使用していますか?コードスニペットはそれを示していますが、おそらくそれは "擬似コード"です。

インスタンスが異なる場合、エンティティの複製が取得されます(yes)。

だから、あなたは3つのオプションがあります。

  • は、コンテキストインスタンスが同じであることを確認してください。
  • は、第二のコンテキストに戻っUtil_LookupValuesを取り付けます

    foreach(Util_LookupValues val in lookupValues) 
    { 
        DataEntities.Util_LookupValues.Attach(val); 
        entity.Util_LookupValues.Add(val);  
    } 
    
  • は、全ての第1のクエリを実行しないでください。代わりに、「スタブ」エンティティを作成し、それらを添付:

    var val = new Util_LookupValues { Id = 1 }; 
        DataEntities.Util_LookupValues.Attach(val); 
        entity.Util_LookupValues.Add(val);  
    
        val = new Util_LookupValues { Id = 2 }; 
        DataEntities.Util_LookupValues.Attach(val); 
        entity.Util_LookupValues.Add(val);  
    

    この作品をEFにのみ、新しい関係を確立するために、コンテキストにオブジェクトを添付する際に、主キープロパティの値を知る必要があるため。

+0

OMG、ありがとう、ありがとう、ありがとう!ルックアップ・エンティティは、再複製されたDomainContext(DataEntities)の別のインスタンスを介して取得されたため、これは実現しませんでした。最初にやり直さなければならないことは、それらを再度添付してコードの残りの部分を進めることです。私はすぐにそれを試みます! – bleepzter

関連する問題