ria domain service is setting a client-side property on callback
I'm using RIA domain services, with entity framework 4 and silverlight 4. When I save changes, when the service call returns, some domain service functions are called wich sets a value to "" that should not be changed at all.
I have two entities
service.metadata.cs:
public partial class EntityA
{
[Key]
public Guid EntityA_Id { get; set; }
public string Name { get; set; }
public int EntityB_Id { get; set; }
[Include]
public EntityB entityB { get; set; }
}
public partial class EntityB
{
[Required]
public string Name { get; set; }
public int EntityB_Id { get; set; }
public EntityCollection<EntityA> entityA { get; set; }
}
On the client side I have a Extra property on EntityA to expose the Name property od EntityB. The server side and domain service never need to know about this property, its for GUI only.
public partial class EntityA
{
//Tags I have tried:
//[IgnoreDataMember]
//[XmlIgnore]
//[Ignore]
//[Exclude]
public string NameOf_EntityB
{
get
{
return this.entityB == null ? string.Empty : this.entityB.Name;
}
set
{
this.entityB.Name = value;
}
}
}
If I edit the entityA's name and call serviceContext.SubmitChanges(), when the call returns some domain service process is setting the EntityA.NameOf_EntityB = ""; So from a user point of view, they save one value and the other blanks out.
I need to stop this from happening. I have tried various data attributes, but they either don't work on the client side, or have no effect.
Any idea what to do to stop the domain service from changing this value?
here's the callstack right before the value is changed:
System.ServiceModel.DomainServices.Client!System.Servic开发者_高级运维eModel.DomainServices.Client.ObjectStateUtility.**ApplyValue**(object o, object value, System.Reflection.PropertyInfo propertyInfo, System.Collections.Generic.IDictionary<string,object> originalState, System.ServiceModel.DomainServices.Client.LoadBehavior loadBehavior) + 0x74 bytes
System.ServiceModel.DomainServices.Client!System.ServiceModel.DomainServices.Client.ObjectStateUtility.ApplyState(object o, System.Collections.Generic.IDictionary<string,object> stateToApply, System.Collections.Generic.IDictionary<string,object> originalState, System.ServiceModel.DomainServices.Client.LoadBehavior loadBehavior) + 0x330 bytes
System.ServiceModel.DomainServices.Client!System.ServiceModel.DomainServices.Client.Entity.ApplyState(System.Collections.Generic.IDictionary<string,object> entityStateToApply, System.ServiceModel.DomainServices.Client.LoadBehavior loadBehavior) + 0x68 bytes
System.ServiceModel.DomainServices.Client!System.ServiceModel.DomainServices.Client.Entity.Merge(System.ServiceModel.DomainServices.Client.Entity otherEntity, System.ServiceModel.DomainServices.Client.LoadBehavior loadBehavior) + 0x5a bytes
System.ServiceModel.DomainServices.Client!System.ServiceModel.DomainServices.Client.DomainContext.ApplyMemberSynchronizations(System.Collections.Generic.IEnumerable<System.ServiceModel.DomainServices.Client.ChangeSetEntry> changeSetResults) + 0x10e bytes
System.ServiceModel.DomainServices.Client!System.ServiceModel.DomainServices.Client.DomainContext.ProcessSubmitResults(System.ServiceModel.DomainServices.Client.EntityChangeSet changeSet, System.Collections.Generic.IEnumerable<System.ServiceModel.DomainServices.Client.ChangeSetEntry> changeSetResults) + 0x262 bytes
System.ServiceModel.DomainServices.Client!System.ServiceModel.DomainServices.Client.DomainContext.CompleteSubmitChanges(System.IAsyncResult asyncResult) + 0x1cb bytes
System.ServiceModel.DomainServices.Client!System.ServiceModel.DomainServices.Client.DomainContext.SubmitChanges.AnonymousMethod__5() + 0x2e bytes
Edit: found a work around for now. In the callback of the ServiceContext.submitChanges() call I can call ServiceContext.RejectChanges() to undo the change that was made to EntityB. I don't trust this solution though as other changes could have been made before the async call returns and those changes would be rejected as well. The ideal solution would be to have that value ignored and NOT set at all
You may need to tell WCF RIA a little more about your entities with some attributes:
public partial class EntityA
{
[Key]
public Guid EntityA_Id { get; set; }
public string Name { get; set; }
public int EntityB_Id { get; set; }
[Include]
[Association("EntityA-EntityB", "EntityA_Id", "EntityB_Id", IsForeignKey=false)]
public EntityB entityB { get; set; }
}
public partial class EntityB
{
[Required]
public string Name { get; set; }
[Key]
public int EntityB_Id { get; set; }
public Guid EntityA_Id { get; set; }
[Include]
[Association("EntityA-EntityB", "EntityA_Id", "EntityB_Id", IsForeignKey=true)]
public EntityCollection<EntityA> entityA { get; set; }
}
Here's my solution:
private bool isExpanded = false;
public bool IsExpanded
{
get { return isExpanded; }
set
{
string stack = (new System.Diagnostics.StackTrace()).ToString();
if (!stack.Contains("ObjectStateUtility.ApplyState") && isExpanded != value)
{
isExpanded = value;
RaisePropertyChanged("IsExpanded");
}
}
}
精彩评论