I have created a datacontext in my silverlight app which utilized "WCF dataservices" to pull out data from custom Odata repository which in turn takes the values from an XML file, the XML file values keep changing since they represent live data, so the question is :
1) when the original data values change can this be reflected automatically on the context ! (I'm implementing "INotifyPropertyChanged" in the mapped class in the WCF service, but still no effect !)
2) when a record is deleted from the original XML, the context records will not be affected until I clear the data and reload them again !.
anyone can help me with this !
The WCF Data Services client needs to query the OData service to get the new values if the original data values are changed/deleted.
DataServiceCollection implements INotifyPropertyChanged to alert the context when objects are added to or removed from the collection, but it is not aware of any original service data changes on the service side.
Hope this helps.
Related
I'm building a multi-layered Windows VS C# solution that has a WCF Service Library project with EF6.2 loaded, and an ADO.NET Data layer with EF6.2 also.
The EDMX model is built as a 'database first' set of tables from my MSSQL Server Express 2016 server on my laptop. My WCF Service Interface and code
only have properties and methods for one of the tables at this point. And that table has also been built out in logic and data layer methods.
So, I'm testing that service now with the WCF Test Client, and I'm receiving some integer data correctly in my service's response from to the data layer, but no string data.
While testing my "GetMemberByID" method, it returns all String column results as a value of "(null)", and a type of "NullObject",
but returns Integers with their actual value. The WCF Soap response shows the returned String values as "". But,
the integers are returned like this: "7". There are over 50 data rows in my test database which is used as the source
for the EF6.2 EDMX build. My App.config's in data and service layers are referencing the same (localdb)\ V13.0 server and database.
Has anyone had this issue, and can you tell me what I'm missing? The MSSQL database was originally an (OleDb) MS Access database and I imported it into
MSSQL Server. Thanks in advance.
It seems that there is something wrong with the serialization process. On my side, the string field can be returned properly. By default, the DataContractSerializer is used to deserialize/deserialize the complex object data.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/using-data-contracts
The most possible reason might be that the nullable field is not decorated by the [DataMember] attribute. Please check if the column of the DataContract autogenerated on the client-side contains the [DataMember] attribute.
http://sivakrishnakuchi.blogspot.com/2010/05/troubleshoot-wcf-service-returning.html
Feel free to let me know if the problem still exists.
Okay, I found my mistake. When translating the business domain objects back to the Service objects in the Service.cs code file, I was only translating the MemberID and the RowVersion - and no other columns. So, the only thing that was showing up in the WCF Test Client result was the MemberID and the RowVersion - which happen to be the only two non-strings in my entity. All the string types were null because I was not translating them back into the Service. Thanks for taking a look at this, Abraham, but you made me start looking closer, and thanks for the advice. The MS Documentation was helpful, too. Once I did a full "step into" debug trace from the UI through to the Data Layer and back, I was able to see the data translation failure. One more thing, before I could debug step by step all the way to the Data layer and back to the Service layer, I had to fix my "Underlying database did not open" issue that so many have had. I'm hosting my service through my local IIS, and had to make a few changes to the IIS application concerning the user credentials. My App.config is set to use "Integrated Security=True" - which is a "passthrough" credential in the IIS App pools. I had my IIS App set to "Specific User", but was not using a UserID/Password in my Connection String. Once I changed my IIS App to "Passthrough" - I was able to connect, and to debug to the DAL and back.
I have a WCF Data Service that is wrapping an Entity Framework 4 data model. I am connecting a WPF client to the service using the WCF Data Services Client library.
Is it possible in WCF Data Services to undo / cancel changes to tracked objects ?
scenario : In the UI I allow a user to edit an object. I have save and cancel buttons. If the user chooses to save I call SaveChanges() on my WCF context and changes are sent to the database via the WCF service. If the user clicks cancel I want to undo the changes and revert to the original property values of the current object.
I know that the WCF data services client library has change tracking built in - but I cannot find any way at accessing this information.
In Entity Framework the context supports the Refresh method and you can specify RefreshMode.StoreWins and pass in the object - this will effectively cancel / undo any changes.
documented here : http://msdn.microsoft.com/en-us/library/bb896255.aspx
Any suggestions on how I can achieve the same thing in WCF DataServices in my client application ?
cheers
Chris
The only "solution" I know of is:
var oldMergeOption = _service.MergeOption;
_service.MergeOption = MergeOption.OverwriteChanges;
try {
_service.YourQueryable.Where(x => x.Id==oldObject.Id).Single();
} finally {
_service.MergeOption = oldMergeOption;
}
This should replace the values of "oldObject" with the values stored in the DB. However, I'm not sure if the object returned by Single() will always be the same as "oldObject".
I typically refrain from operating on entities within the DataServiceContext until I'm ready to commit those changes to the database. I don't treat my entities as part of my domain model so I create a specific domain model that adapts my model objects to entity objects using adapters and a repository class. This way, all operations within by domain model are self-contained until I'm ready to commit them to the database. A fantastic article from Ben Day on what I'm referring to can be found here: http://visualstudiomagazine.com/articles/2011/04/01/pfcov_silverlight-mvvm-tips.aspx
I guess this has been asked before here , but I'm still confused about the correct approach to be taken.
I have a WPF client application which talks to a WCF service to retrieve data.
On the Service side , I have a large entity ( around 25 properties) and I have
three forms in my client app .
On each form, I need the facility to edit certain properties of my domain entity.
I do not want to return the large entity through the service as I need just 3-4 of its properties on each form.
Hence I have created three DTOs ( we are using AutoMapper) , one for each screen.
The service returns DTOs and this works very fine as far as the retrieval goes.
My question is how do I persist my DTOs.
We are using NHibernate in the service layer.
If I pass my partial DTOs to the service to persist , I would need to reload my large entity every time to perform the update.
Is this the only way to handle this scenario ?
What other options do I have if I need to display partial views of one single entity on the UI .. besides sending across the whole entity over the wire ..or creating three DTOs?
Thanks.
Using NHibernate in the service layer it is logical that you will need to either:
a) load the entity during an update operation at the service, modify the required properties and then commit your transaction, or
b) if you have the object already available at the service (but not associated with the NHibernate session) then you can modify the required properties, call session.Update(obj) to reassociate the object with the session and then commit your transaction.
We use the first approach regularly where we have hundreds of different entities in our model. We pass specialised command request objects from client to server and then our service layer is responsible for performing the work specified in the command requests.
Alternatively you could formulate a HQL query as outlined here. But this will quickly get pretty ugly and difficult to maintain.
We are using a WCF Data Service to broker our data server side, and give third parties easy OData access to our data. The server side of things has been relatively easy. The client side, on the other hand, is giving us fits.
We are converting from regular Entity Framework to Data Services, and we've created an assembly which contains the generated client objects that talk to the data service (via a Service Reference). Those classes are partial, so we've added some logic and extended properties to them. This all works great.
The issue we are having is that we need to process our objects at save time, because they need to do some advanced serialization before they are sent over the wire. The DataServiceContext class contains two events: WritingEntity and ReadingEntity. The ReadingEntity event actually happens at the correct time for us (post object deserialization). The WritingEntity event happens at the WRONG time for us (post object serialization).
Is there any way to catch an object before it's written to the request, so that we can call a method on entity that is about to be written?
Obviously we could just loop through the Entities list, looking for any entity that is not in a state of Unchanged or Deleted, and call the appropriate method there...but this would require me to add special code every time I wanted to call SaveChanges on the context. This may be what we need to do, but it would be nice if there was a way to catch the entities before they are written to XML for sending to the service.
Currently there's no hook in the DataServiceContext to do what you want. The closest I can think of is the approach you suggested with walking all the entities and findings those which were modified. You could do this in your own SaveChanges-like method on the context class (which is also partial).
I got a class called "Board" and one of its property's is an ObservableCollection. When i send the ObservableCollection through WCF (from server to client) end call it from my proxy, it's turned into an Array, which is no good for me.
Can i keep the ObservableCollection after being sent, or do i have to kick the Array till it becomes an ObservableCollection again?
Check out the 'Configure Service Reference' option in the context menu in VS for the reference. You can choose the collection type that is transmitted across the service. By default I think it is set to array but there are several choices (I believe list and observablecollection are options).
EDIT: I just checked, and unfortunately observable collection is not one of the choices. It looks like you'll have to pick from:
Array
ArrayList
LinkedList
List
Collection
BindingList
By default - no, you cannot do anything about it. WCF will serialize your structures into something that can be represented with XML schema. XML Schema has no knowledge of anything but raw, and fairly simplistic data structures. You can only transfer concrete, raw data - no "magic" behavioral addon.
There is one solution to the problem, IF you own both ends of the wire: you could put your service and data contracts into a separate class library assembly, and share those between server and client. In that case, you only ever have one single implementation of your data contract - your ObservableCollection.
If you share that assembly between your service (implementation) class, and the client (add the reference to that assembly before you "Add Service Reference" from Visual Studio!), then your client should pick up that ObservableCollection and continue to use that (instead of creating a XML schema compatible Array on the client side).
Thank you both for the answer.
I will look at both solutions when i continue the project, and will start with try and change the Collection send through the wcf service.
I'll let you know what works for me...