EF with WCF - List< > only first element references updated
- Hi,
We have a database with this tables:
CarModel represent a car, a car is of a color type.
ColorType represent a color range, a color type contains a lot of colors.
ColorTypeValue represent one color.
The relationships between tables are:
CarModel has a FK to ColorType table (the range of color options)
CarModel has a FK to ColorTypeValue table (the selected color of the car)
ColorTypeValue has a FK to ColorType table (the color type of the value)
We have a EF Model like this:
CarModel (* - 0..1) ColorType
CarModel (* - 0..1) ColorTypeValue
ColorType (0..1 - *) ColorTypeValue
the idea is to present to user a car model which is of a ColorType and allow user to select one of the ColorTypeValue's of the ColorType and save it on the CarModel property.
Client call asynchronous method on server (WCF) to get all CarModel. The server method is like this
public List<CarModel> GetAllCarModel() { using (TestEntityReferenceEntities context = new TestEntityReferenceEntities()) { // Include all CarModel references and ColorType.ColorTypeValue return (from o in context.CarModel .Include("ColorTypeValue") .Include("ColorType") .Include("ColorType.ColorTypeValue") select o).ToList(); } }
Client shows original values (suppose all car model are of ColorType 1 and its value ColorTypeValue is of value 1)
and update all car model's to set the second ColorTypeValue of the ColorType, for example:
private void Button_Click(object sender, RoutedEventArgs e) { ServiceReference1.Service1Client sc = new TestEntityReference.ServiceReference1.Service1Client(); List<CarModel> oo = sc.GetAllCarModel(); foreach (CarModel o in oo) { // Show original values Debug.WriteLine(string.Format( "Car Model:{0} - Value:{1}", o.Description, o.ColorTypeValue.IdColorTypeValue)); // Set second value of the possible color's list o.ColorTypeValue = o.ColorType.ColorTypeValue[1]; } sc.Save(oo); sc.Close(); }
Client show the next output:
Car Model:Car 1 - Value:1
and call Save, sending the updated list to the server again.
Car Model:Car 2 - Value:1
Car Model:Car 3 - Value:1
public bool Save(List<CarModel> master) { foreach (CarModel o in master) { Debug.WriteLine(string.Format("Car Model:{0} - Value:{1}", o.Description, o.ColorTypeValue.IdColorTypeValue)); } return true; }
If we examine the updated list on the server method we realize that only the first element of the list was updated, the rest remain with the original values. The output is:
Car Model:Car 1 - Value:2
Car Model:Car 2 - Value:1
Car Model:Car 3 - Value:1
if we change the way to retrieve objects, changing this (in GetAllCarModel method):return (from o in context.CarModel .Include("ColorTypeValue") .Include("ColorType") .Include("ColorType.ColorTypeValue") select o).ToList();
for this
return (from o in context.CarModel .Include("ColorTypeValue") select o).ToList();
and in client function changing this (in Button_Click method)
for thiso.ColorTypeValue = o.ColorType.ColorTypeValue[1];
o.ColorTypeValue = new ColorTypeValue { IdColorTypeValue = 2, Description = "void" };
everything works fine, but we are using a dummy reference object to provide the color.
Are there some limitations serializing this kind of relationships of EF over WCF. Is so, why only the first element in the collecion is able to send the updated value?
I don't know how attacht a file into a post. If someone is interest I could send a project sample code.
Thanks all.
All Replies
- Hi ayus,
Could you post the updating code?
It can be caused by updating not reaching the other two entities.
Here is a similar thread for your reference,
http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/c19b6a9e-f23a-473a-bb16-06a7df468319
Please update the thread, we'll have a further discussion.
Best Regards
Yichun Feng
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
- Hi Yichun, thank for the information.
The update code is the one I post previously, in the client code. In Button_Click, I retrieve the list of objects calling server method GetAllCarModel(). This code, includes for all objects the ColorType reference, each ColorType also include ColorType.ColorTypeValue which is a list of all possible values of the ColorType. After GetAllCarModel call, I update all objects setting the ColorType.ColorTypeValue to the second options (lets assume, than ColorType.ColorTypeValue list has 3 possible colors).
The update code is o.ColorTypeValue = o.ColorType.ColorTypeValue[1];
And I call server method Save, sendind the "updated" list again to the server. On the Save method I do nothing because I realize that only the first element of the list is updated to the o.ColorType.ColorTypeValue[1]; The rest remains with the original values. Of course the intention in the Save method is update the database using EF (but the values client send are not correct).
I don't know if it's a problem with the way WCF serialize the EF list of objects or is a problem with the way I update the reference of each objects, but I'm very interest to know why only first element is updated....
If the post is not enough clear I'll try to explain the problem in a better way. Please, ask me any question.
Thanks again and best regards.
Ayus - Hi Yichun,
Reviewing your answer and all related information and analyzing the phrase "It can be caused by updating not reaching the other two entities", I do some changes in code. Before update the value, I remove the CarModel reference from the ColorType.ColorTypeValue list.
// Remove CarModel reference from ColorTypeValue o.ColorType.ColorTypeValue.Find(x=> x == o.ColorTypeValue).CarModel.Remove(o); // Set second value of the possible color's list o.ColorTypeValue = o.ColorType.ColorTypeValue[1];
That way, values are send ok to the server. In the first case, I only updated the ColorTypeValue property of the CarModel objects. But ColorType.ColorTypeValue still have a relationship to the CarModel object. So, when client send to server all the objects, WCF serialization "restore" the update values because there was a relationship between objects.
In this second case, only one relation between CarModel and ColorType value exists, so server receive values ok.
I think, it's maybe a problem with the way I update the values (and all references between objects) than a problem of EF and WCF serialization, isn't it? Hi ayus,
Do you mean that if you only update CarModel and CorlorType will be OK?
And if you want to update the three entities at same time, there will be problem?
Would you mind give a clear steps that on both client and WCF while updating?
I’ll consult the product team for your issue at spear time. If there are any replies form them, I will let you know immediately.
Thank!
Yichun Feng
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
- Hi Yichun, first of all thanks for your support and sorry about so late answer, but I want to post the clear steps.
Regarding your asks, it is not exactly what happens. If I only update CarModel.ColorValueType property but not update the CarModel.ColorType.ColorTypeValue list then there is the problem on server side (only the first element of the CarModel list I get is properly updated).
I'm trying to explain clearly all the steps:
1) From database, EF generates these classes (I only show properties with relationship between classes):
- CarModel
o ColorType property
o ColorTypeValue property
- ColorType
o EntityCollection<ColorTypeValue> property
o EntityCollection<CarModel> property
- ColorTypeValue
o ColorType property
o EntityCollection <CarModel> property
The relationships between classes are
CarModel (* - 0..1) ColorType
CarModel (* - 0..1) ColorTypeValue
ColorType (0..1 - *) ColorTypeValue
2) WCF publish two methods with this signatures
public List<CarModel> GetAllCarModel() ;
public bool Save(List<CarModel> master);
3) Client has a Service Reference to WCF serviceAssume that from server, client gets the List<CarModel> with objects (CarModel 1, CarModel 2, CarModel 3) calling GetAllCarModel() method.
The objects we get from List are:All CarModel’s (CarModel 1, CarModel 2, CarModel 3) have a property ColorType and all of them are reference to the same object. (ColorType 1).
All CarModel’s have a property ColorTypeValue and all of them are reference to the same object (ColorTypeValue 1)
ColorType 1 has a property of type List<ColorTypeValue> (ColorTypeValue 1, ColorTypeValue 2, ColorTypeValue 3)ColorType 1 has a property of type List<CarModel> with objects (CarModel 1, CarModel 2, CarModel 3).
Finally, ColorTypeValue has a property List<CarModel> with CarModel references.
ColorTypeValue 1 has three objects into List<CarModel> (CarModel 1, CarModel 2, CarModel 3)
ColorTypeValue 2 has 0 objects into List<CarModel>
ColorTypeValue 3 has 0 objects into List<CarModel>
4) In client, we update all CarModel.ColorTypeValue property to the object ColorTypeValue 2 with this code:
Also, all ColorTypeValue objects have a property ColorType and all of them are reference to the same object (ColorType 1)
ServiceReference1.Service1Client sc = new TestEntityReference.ServiceReference1.Service1Client();
List<CarModel> oo = sc.GetAllCarModel();
foreach (CarModel o in oo){
o.ColorTypeValue = o.ColorType.ColorTypeValue[1];
}
And send again List<CarModel> to server with method Save().
sc.Save(oo);
sc.Close();
5) In Save method, I only look at how references between objects are.
public bool Save(List<CarModel> master)
{
foreach (CarModel o in master)
{
Debug.WriteLine(string.Format("Car Model:{0} - Value:{1}",
o.Description,
o.ColorTypeValue.IdColorTypeValue));
}
return true;
}
The objects we get from master List areAll CarModel’s (CarModel 1, CarModel 2, CarModel 3) have a property ColorType and all of them are reference to the same object. (ColorType 1).
All CarModel’s have a property ColorTypeValue
CarModel 1 are reference to ColorTypeValue 2
CarModel 2 are reference to ColorTypeValue 1
CarModel 3 are reference to ColorTypeValue 1ColorType 1 has a property of type List<ColorTypeValue> (ColorTypeValue 1, ColorTypeValue 2, ColorTypeValue 3)
ColorType 1 has a property of type List<CarModel> with objects (CarModel 1, CarModel 2, CarModel 3).
Finally, ColorTypeValue has a property List<CarModel> with CarModel references.
ColorTypeValue 1 has two objects into List<CarModel> ( CarModel 2, CarModel 3)
ColorTypeValue 2 has one objects into List<CarModel> (CarModel 1)
ColorTypeValue 3 has 0 objects into List<CarModel>
My ask here is why if I updated all CarModel.ColorTypeValue property to a ColorTypeValue 2 object reference, only the first element in the collection is properly reference on Save method.
Finally, if I remove all ColorType.CarModel references in client method with this code:
List<CarModel> oo = sc.GetAllCarModel();
foreach (CarModel o in oo){
o.ColorType.ColorTypeValue.CarModel.Clear();
o.ColorTypeValue = o.ColorType.ColorTypeValue[1];}
then all CarModel's object are properly reference to ColorTypeValue 2 in Save method, and of courseAll ColorTypeValue object has 0 objects into List<CarModel> .
So, I don't know if there is a problem with serialization with these relationships between WCF and EF model or
when I update one reference between objects I have to update also all possible references between those object in the model (maybe it's the correct answer, but I don't know why first element is ok).
Thanks again Yichun for your interest, I hope I'm not wasting your time.
Best regards.


