views:

398

answers:

4

I'm new to the Entities framework. One week earlier I've hit the common problem of the currentcontext that throws exception if used in a non-unique manner, but that was fixed.

Today I have a new problem, a really new one because I do not even know why this is happening since I do think that I have the same code.

Here is the error that I am getting :

Entities in 'Entities.WSUser_Detail' participate in 
the 'FK_WSUser_Detail_WSCountry' relationship. 
0 related 'WSCountry' were found. 1 'WSCountry' is expected.

What's so strange about this error is that in my code I never reference any WSUser_Detail object. Does anyone has come up with that kind of error? My code is really simple :

newUser = (from user in GB.Context.WSUsers
                where user.IDUser == nFound
                select user).FirstOrDefault();

newUser.DoNotSend = false;
newUser.IP = Request.UserHostAddress;
newUser.LastDtActivity = DateTime.Now;
newUser.Language1 = GB.User.Language;
newUser.LastVersion = sVersion;
newUser.FlushNextTime = false;

GB.Context.SaveChanges();

The error occurs on SaveChanges()

Absolutely no WSUser_Detail is being called in my code... so I wonder why should he ask for a reference that is on an object that is never called (but exists in the Entities Context).

Any idea?

The weird thing is that I do not had this problem before even if the code didn't seem to have changed.

I updated the Model.edmx to be sure that it's not the cause, but it still does not work, I've checked many times and the error shouldn't come AT ALL since I do not have any WSUser_Detail object.

+1  A: 

At the database level, I would guess that you have a foreign key constraint on a field that is not allowed to be NULL .. and you the resulting model has a relationship between the WSCountry and WSUser tables.

It looks like you could be trying to save an invalid entity - one that does not satisfy your constraints..

My guess would be that your WSUser is required to have a WSCountry entity set. Is there a WSUser.WSCountry property to set ?

If my hunch is correct - make sure that this is set before saving.

By the way - 'FK_WSUser_Detail_WSCountry' does not suggest an object - it is referring to a relationship/FK constraint set up in your database. Entity Framework uses these constraints to guess how your entities should be related..

markt
Thanks for this answer. I know that it's due to a NULL value and that it's also seem to be due to a relationship that failed, but as I said on my post there is no such link between WSUser and WSCountry.That's why this is so weird to me... this error wasn't happening before and I do not know what changed but there is still no link at all between the WSUser table and the WSCountry. No database relationship was changed at all, the only thing that could fail is the code but in my case the code shouldn't fail at all since I do not touch to an entitiy object that needs a reference to WSCountry.
Micael
Maybe you could post a bit more detail about your entity model structure - it is hard to guess without knowing what you have.Are there entities like User->UserDetail->Country ?
markt
+1  A: 

With this little SQL script which inspects the sys system catalog views, you should be able to find out which database constraint between which two tables (and their columns) is involved in this problem - check it out, most likely, this is a required reference, e.g. you cannot leave it empty (and you probably do in your code right now).

SELECT
    fk.name ,
    t1.Name 'Parent table',
    c1.Name 'Parent column',
CASE WHEN c1.is_nullable = 0 THEN 'No' ELSE 'Yes'
END AS 'Parent column nullable',
    t2.Name 'Referenced table',
    c2.Name 'Referenced column'
FROM 
    sys.foreign_keys fk
INNER JOIN 
    sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
INNER JOIN 
    sys.tables t1 ON fkc.parent_object_id = t1.object_id 
INNER JOIN 
    sys.tables t2 ON fkc.referenced_object_id = t2.object_id
INNER JOIN 
    sys.columns c1 ON t1.object_id = c1.object_id AND fkc.parent_column_id = c1.column_id
INNER JOIN 
    sys.columns c2 ON t2.object_id = c2.object_id AND fkc.referenced_column_id = c2.column_id
WHERE 
    fk.name = 'FK_WSUser_Detail_WSCountry'

This should give you the parent table and column as well as the referenced table and column - e.g. the two parties involved in your foreign key relationship.

That should hopefully clear up what piece of the puzzle you're missing.

marc_s
Hi! Unfortunately (in a way if that would have been that I would have been happy because I would've knew what's wrong in my system) my database is correct, I've ran your script and it shows as I expected (because I've already checked the constraints since the Stacktrace of the exception was talking about constraint checking.There is the only result of your script :FK_WSUser_Detail_WSCountry WSUser_Detail IDCountry No WSCountry IDCountryThe result is correct and I expected it, there is only one and only link and it's between WSUser_Detail and WSCountry. Nothing is being linked to WSUser.
Micael
A: 

Your model (EDMX) says that there is a 1:1 relationship between WSUser and WSUser_Detail, but your question implies that you expect the relationship to be 1:0..1, so either your own understanding or your model is incorrect. If the model has the cardinality of the relationship at 1:1, then the Entity Framework will check this whenever you create or save a WSUser entity. This is the source of the error you are seeing.

Because your question implies that this is the wrong cardinality for this relationship, you probably want to go and fix the EDMX. To do this, find the FK_WSUser_Detail_WSCountry association in the Model Browser. Click that, and expand the two End properties in the Properties window. Change the Multiplicity of the appropriate End.

Craig Stuntz
A: 

I finaly found what the problem was!

I was using a global Context as shown here. But in some previous tests I added a user detail that wasn't containing any wscountry reference that is required. So it first ran into an exception, which is what I could expect.

The real problem is that whenever an invalid entity object is added with the method AddTo(entityObj), any further call to SaveChanges() will try to add that object into the context, even if the page that caused the problem does not exist anymore since the Context object was "corrupted".

So every call to SaveChanges() would be denied by an Exception after any AddTo with an invalid entity object...

My question would be : is it possible to have an information like the validity of the entity BEFORE trying to add it in the used context? Because fatal error like this are logical but hard to understand since it's showing an error that was done several hours ago (when working on an ASP.Net project using a global context).

Micael