views:

54

answers:

2

Hello,

I am using the Entity Framework with a MySQL server because I want to be able to do nice and easy LINQ queries againy my MySQL database. I have a very simple problem and I'm frustrated because I can't believe that the EF is making such a horrible mistake.

To simplify, I have parent and child classes, and I want to execute two inserts in one transaction.

To demonstrate: I have A, B, C and D. A is parent of B and C, B and C are parents of D (it needs to be like that).

I do the following:

B b = new B() { B_ID = 1 };
A.Bs.Add(b);
C.Ds.Add(new D() { B_ID = b.B_ID } );

I am doing it this way because all this actually happens inside the C class. Why am I getting an UpdateException (Entitities in '...' participate in the 'BD' relationship. 0 related 'B' were found. 1 'B' is expected)? Because when I leave out the last command (inserting D, child of B) it works fine, and when I issue an insert afterwards (ie. in a new transaction), it works fine as well.

Can it be that EF is blindly inserting elements in a random order, but noticing for itself that it can't be? Or am I approaching the problem in a completely wrong way?

EF version: I have the .NET FX 3.5 SP1, so from what I know it is version 1.

Update: Very sorry, tracked down the error to a mistake I made, so now the error doesn't happen on the EF level (with the exception I said above), but actually an INSERT for the chidl element is sent to the DB, I can see it in the log. So the problem still persists, but the exception is different (a foreign key constraint fails).

Thank you for your help, Michael

(edited to answer comments)

+2  A: 

Does b.B_ID represent an identity column (or other ID that's autogenerated by the database)? If so, then it won't have a usable value until after its insert operation takes place. In this case, you'll have to set one side of the relationship using an object reference rather than a database identifier.

Either:

C.Ds.Add(new D() { B = b });

Or

b.Ds.Add(new D());
Adam Robinson
b.B_ID is a key column, but the value is usable, since I am actually setting it after constructing B (it's the "..." party, going to change the original post, sorry)
Michael
@Michael: Have you tried one of the suggestions I made? I'm not saying that your way *shouldn't* work, but I'm curious if one of those options will allow you to insert them in the same batch.
Adam Robinson
@Adam: Yes, and it helped me find out that I made some pretty beginner-like mistakes in my surrounding code, so thank you very much for those :-) but now I'm still stuck with the INSERTs coming in the wrong order!
Michael
@Michael: So, just to confirm, it works fine if you use object references, but not when you use explicit ID's, correct?
Adam Robinson
No, unfortunately it does not work fine with object references either. And of course when I try to create a new project, an isolated example of exactly these 4 tables (A, B, C, D) to reproduce the problem, it all suddenly works :-(
Michael
@Michael: First, I'd try updating your existing .edmx from the database (right click->Update Model from Database->Refresh). If that doesn't work, was your error related to your usage of EF in code or in something you did in the designer?
Adam Robinson
@Adam: No, unfortunately updating didn't help either. My error was that I set a wrong B_ID while constructing the D, so the EF was actually right saying that there is no corresponding B found.The problem that's left now is simply the fact that the INSERTs are coming in the wrong order.Plus, updating to VS2010 to use the EF2 is currently not an option for me...
Michael
@Michael: (Actually, it's EF4 that's part of VS2010). I'm not sure what else would be the problem. Hopefully someone else can post an answer.
Adam Robinson
Thanks, and just out of couriosity, what version of EF is part of VS2008 SP1 that I'm working on? Hope to be able to buy VS2010 soon ...
Michael
@Michael: That's version 1; EF 4 is called EF4 just because Microsoft decided to standardize a lot of version numbers to correspond with the .NET version number starting with 4.
Adam Robinson
A: 

After hours of trying around I think I've had a breakthrough. This needs some more testing but I found that the EF can handle INT relationships much better than VARCHAR(n) ones. Going to update this answer as soon as I know it.

Just though someone else would be struggling as well...

Edit: Yup, definitely. For my configuration (EF1/MySQL), the EF puts child-INSERTs first if the primary key of the parent (and the foreign key of the child) is a VARCHAR. I tried with VARCHAR(120) and VARCHAR(255), none worked.

Michael