1

In working with EF Database first, I am not being able to insert records into a specific table. I get the INSERT statement conflicted with the Foreign Key... error.

My question:

Assuming EF requires you to perform only a single dbContext.SaveChanges() at the end of your changing process, does the order you add records to the DbSets has effect on this ? Or it does not matter since the DbContext keeps track of all the changes made to the data and is itself responsible to apply them in the proper order ?

To illustrate, for 3 tables A, B and C, where B has a FK on A and C a FK on B, if I manually loop over all records I have to add to C, B and A - and do DbSet<C>.Add() before I issue DbSet<B>.Add() is problematic ? Is it required to issue a dbContext.SaveChanges() for each table additions ?

Adding the create sql script for all 3 tables:

CREATE TABLE [dbo].[A](
    [Id] [int] NOT NULL,
    [a1] [int] IDENTITY(1,1) NOT NULL,
    [a2] [nvarchar](50) NULL,
 CONSTRAINT [PK_A] 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],
 CONSTRAINT [IX_A] UNIQUE NONCLUSTERED 
(
    [a1] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]



CREATE TABLE [dbo].[B](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [a1] [int] NULL,
    [b1] [int] NULL,
    [b2] [nvarchar](50) NULL,
 CONSTRAINT [PK_B] 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],
 CONSTRAINT [IX_B] UNIQUE NONCLUSTERED 
(
    [b1] 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].[B]  WITH CHECK ADD  CONSTRAINT [FK_B_A1] FOREIGN KEY([a1])
REFERENCES [dbo].[A] ([a1])
GO

ALTER TABLE [dbo].[B] CHECK CONSTRAINT [FK_B_A1]
GO


CREATE TABLE [dbo].[C](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [b1] [int] NULL,
    [c1] [int] NULL,
    [c2] [nvarchar](50) NULL,
 CONSTRAINT [PK_C] 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

ALTER TABLE [dbo].[C]  WITH CHECK ADD  CONSTRAINT [FK_C_B] FOREIGN KEY([b1])
REFERENCES [dbo].[B] ([b1])
GO

ALTER TABLE [dbo].[C] CHECK CONSTRAINT [FK_C_B]
GO

I know what the error aforementioned means, but I could not find yet which data is incorrectly linked/inconsistent.

And by the way, why such errors (INSERT statement conflicted with the Foreign Key...) are not "caught" in GetValidationErrors() ?


Update:

The problem must be the way I am trying to populate the tables. But how should this be done then ?

For the scenario below:

enter image description here

private static void Main(string[] args)
{
    //Validate_Xml_Against_Xsd.ValidateXmlAgainstXsd example = new Validate_Xml_Against_Xsd.ValidateXmlAgainstXsd();
    //example.Run();

    TestEntities t = new TestEntities();

    A a = new A { a1 = 1000, a2 = "aaa" };
    B b = new B { a1 = 1000, b1 = 87141, b2 = "bbb" };
    C c = new C { b1 = 87141, c1 = 1, c2 = "ccc" };

    t.C.Add(c);
    t.B.Add(b);
    t.A.Add(a);

    //changing the order does not fix it
    //t.A.Add(a);
    //t.B.Add(b);
    //t.C.Add(c);

    int s = t.SaveChanges();

    Console.WriteLine(s);
}

How should the tables be populated ? Both my DbSet.Add() attempts fail with

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_B_A1". The conflict occurred in database "Test", table "dbo.A", column 'a1'.
The statement has been terminated.
Veverke
  • 9,208
  • 4
  • 51
  • 95
  • Is `A.a1` a key property? The error means you're setting some foreign key column to a value that doesn't have a matching record in the associated table. – jjj Sep 01 '15 at 04:41
  • A.a1 does not map to a A's key, because A's key is Id. `doesn't have a matching record in the associated table` - I know. – Veverke Sep 01 '15 at 12:54
  • ooooh, you're trying to use a non-key column as a foreign key. I don't think EF supports that. – jjj Sep 01 '15 at 17:08
  • That's the thing, I opened a [new question on this topic](http://stackoverflow.com/questions/32327153/are-navigation-properties-generated-only-for-fks-on-pks-as-opposed-to-unique-ke). – Veverke Sep 02 '15 at 07:12
  • With EF, key columns in the model don't necessarily have to be the same columns as the columns with the primary key constraint in the database, though I'm not sure how you configure that using database first. You might be able to use that to your advantage (especially if the primary key isn't used as a foreign key reference elsewhere). – jjj Sep 02 '15 at 17:35
  • @jjj: thanks for your efforts, no, the PKs are not used elsewhere, indeed. That's the thing, I still need to figure out why seems like the unique-keys FKs are not being "translated" into my edmx. – Veverke Sep 03 '15 at 09:57

1 Answers1

1

No, the order is not important. The problem here is that you seem to have foreign keys but you lack navigation properties and you never set relations between entities.

Thus, when B is persisted, it doesn't point to any valid A. A correct code should look somehow like

A a = new A() { ....
B b = new B() { a = a, ...

assuming that your navigation property from B to A is called a.

Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106
  • Hi Wiktor, thanks for replying. This means that the relationships must be *implemented manually*. I mean, I have to set the navigation properties programmatically ? This is what was not clear. – Veverke Sep 01 '15 at 07:42
  • My problem is figuring out why, indeed, the tables were created **without** their navigation properties. I have posted this as a [new question](http://stackoverflow.com/questions/32327153/are-navigation-properties-generated-only-for-fks-on-pks-as-opposed-to-unique-ke). – Veverke Sep 01 '15 at 08:43
  • What exactly is this foreign key? Which column it involves? Could you post its exact definition rather than the database diagram? – Wiktor Zychla Sep 01 '15 at 11:48
  • Updated per your request. – Veverke Sep 01 '15 at 12:51
  • @Veverke: I am not sure EF supports navigation properties to columns that are not primary keys. Are you sure this is supported at all? This http://stackoverflow.com/questions/16035396/entity-framework-add-navigation-property-with-non-primary-key seems to be a piece of evidence it doesn't. – Wiktor Zychla Sep 04 '15 at 07:17
  • That's what I am trying to assert. – Veverke Sep 06 '15 at 07:19