views:

130

answers:

3

I have a Client entity and PostCode entity in Linq to SQL model. The Clients table in database contains client_postcode column which is a FK column to postalcode column in PostCode table, which is a varchar column primary key for PostCode table.

When updating Client, in my code I do this

        // postcode
        updating.PostCode = (from p in ctx.PostCodes
                             where p.postalcode.Equals(client.PostCode.postalcode)
                             select p).First();

where client object is provided from ASP.NET MVC View form. This code seems to set the PostCode related entity fine. But when calling SubmitChanges() I receive the following exception:

Value of member 'postalcode' of an object of type 'PostCode' changed. A member defining the identity of the object cannot be changed. Consider adding a new object with new identity and deleting the existing one instead.

So I am currently unable to change the related entity. How is that done in Linq to Sql?

UPDATE:

After further review and troubleshooting I found out that the problem is in ASP.NET MVC UpdateModel() call. If I call UpdateModel() to update the existing entity with the edited data, something is wrong with the FK assignement for PostCode. If I don't call UpdateModel and do it by hand, it works. Any ideas what goes wrong in UpdateModel() that it can't set the relationship to foreign key entities correctly?

I am updating this question and starting a bounty. The question is simplified. How to successfully use L2S and UpdateModel() to work when updating items (with related entities as FK) in ASP.NET MVC Edit views?

A: 

Wouldn't updating.client_postcode = client.client_postcode; accomplish what you want?

Client.PostCode should be looked up on seek based on client_postocde.

James Curran
If I do this, it says: Operation is not valid due to the current state of the object. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException: Operation is not valid due to the current state of the object.
mare
A: 

You can not do what you are trying, you cannot change the Postcode like that.

James' idea is in the right direction.

Updatemodel() takes the matching values from the Formcollection

How do these values come in the Formcollection? What are their keys?

basically there are 2 ways in editing an object.

option 1:

all the value names you want to update have corresponding keys in the Formcollection, which leaves you just to call UpdateModel() of the original object. do SubmitChanges()

option 2:

Get the original object, change it's values manually (because the keys dont correspond) and do SubmitChanges()

you are tying to change a link, you cant do that. you can only edit the updating.client_postcode which in this case is a string?

Can you please copy the whole action here? So I can write some code for you without gambling.

Stefanvds
I had my controller action both with just UpdateModel() (in which case I get the exception mentioned in my question) and without it and manually setting the properties of a original object (in this case there is an exception that I provided in my comment to James' answer).
mare
Also what you say is wrong, you can and should change the related entity by changing the association property not the FK itself, look here http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/744b2c6a-ecb8-44bf-b72a-dc1b85b34342/
mare
can you just post the whole action method? because clearly something is wrong... and it's not shown in the code you provided.
Stefanvds
@Stefanvds I find it likely that the OP is telling you what is. I find it perfectly reasonable than the UpdateModel is getting postcode.postalcode in the form collection and trying to update it. @mare can you confirm? / check my answer.
eglasius
+1  A: 

It seems to me that you are receiving PostCode.postalcode in the http post request.

Based on how model binding works, the UpdateModel call updates .PostCode.postalcode of the model you are passing to it.

Use this overload to include or exclude specific properties.

eglasius
this is so far the closest answer though I cannot confirm it just yet. Upvoting.
mare