4

Ich habe ein sehr umfangreiches Projekt programmiert und habe Probleme mit EF4- und Joiner-Tabellenoperationen bekommen.Entity Framework 4 - So fügen Sie Datensätze mit Joiner-Tabellen ein C#

Angenommen, haben wir die folgende SQL-Tabelle 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 

Sobald ein Domänenmodell auf diesen Tabellen basiert crated wird Sie mit zwei Entitäten würden am Ende: SqlEntity und Util_LookupValues.

An diesem Punkt ist die Util_LookupValues ​​eine Tabelle, deren Werte nur für Suchvorgänge definiert wurden! Die Xref_EntityValues ​​ist eine Joiner-Tabelle, die das Entity-Objekt mit dem Lookup-Wert verknüpft, so dass wir eine meny-to-meny-Beziehung zwischen den beiden haben und die "Lookup" -Funktionalität für die Lookup-Tabelle beibehalten können.

Util_LookupValues ​​Inhalt

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

Wenn keine Änderungen an das Domänenmodell hinzugefügt werden (Lets für die Zwecke dieser Frage nennt es DataEntities) dann eine SQLEntity mit Util_LookupValues ​​Objekten, dessen PK bindet 1 und 2 wären geschah wie folgt:

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

Problem ist aber, dass statt nur Werte an den Xref_EntityValues ​​Zugabe auch dieser Code eine Kopie von 1 und 2 zu den Util_LookupValues ​​mit neuen Schlüsseln ergänzt! Die resultierende Datenbank ist wie folgt:

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 

Wie mache ich es, dass nur Util_LookupValues ​​die 2 ursprünglichen Aufzeichnungen hat und die Xref_EntityValues ​​hat die richtigen Fremdschlüssel?

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

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

Ich vergaß zu erwähnen, dass ich etwas eingeschränkt bin, wie viel Änderungen ich an SQL machen kann. Da dieser Code in einem Silverlight 4-Projekt verwendet wird, sind für Änderungen am Domänenmodell auch Änderungen an allen WCF RIA-Diensten und eine extrem große Codebasis erforderlich. – bleepzter

Antwort

3

Ist diese Zeile ...

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

... und diese Linie ...

DataEntities.SQLEntities.Add(entity); 

... verwenden die gleiche Instanz des DataEntities Kontext? Ihr Code-Snippet zeigt das an, aber vielleicht ist es "Pseudocode".

Wenn die Instanzen unterschiedlich sind, erhalten Sie die Duplizierung von Entitäten, ja.

Also, haben Sie drei Möglichkeiten:

  • Sicherstellen, dass die Kontext-Instanzen gleich sind.
  • Bringen Sie die zurück Util_LookupValues auf den zweiten Kontext:

    foreach(Util_LookupValues val in lookupValues) 
    { 
        DataEntities.Util_LookupValues.Attach(val); 
        entity.Util_LookupValues.Add(val);  
    } 
    
  • nicht die erste Abfrage überhaupt durchführen Sie. Stattdessen „Stummel“ Entitäten erstellen und fügen Sie sie:

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

    diese Arbeit, weil EF braucht nur den Primärschlüssel-Eigenschaftswert wissen, wenn Sie ein Objekt in den Kontext fügen Sie eine neue Beziehung aufzubauen.

+0

OMG, Danke, danke, danke! Ich habe nie realisiert, dass die Lookup-Entities über eine andere Instanz des DomainContext (DataEntities) repliziert wurden! Ich denke, das erste, was ich tun muss, ist, sie wieder anzubringen und dann mit dem Rest des Codes fortzufahren. Ich werde es sofort versuchen! – bleepzter

Verwandte Themen