This question is locked. New answers and comments are not allowed.
Hello,
I'm evaluating OpenAccess as our ORM for a client-server scenario and I have some doubts on how things should be approached. I have a DB in SQlite with some tables, for this example I have a table called Projects and another called Sites. A Project can contain many Sites and a Site can only be part of a single Project. Both tables also have a Description field for adding text information.
I created a Class Library project where I created an OpenAccess Domain Model with my entities (I used attributes for the mappings).
Then I created a WCF Service Application (to get around the limitation of the Data Services Wizard when selecting projects). I told the wizard to generate the service on a new class library called Service. The Data Services Type is WCF EndPoints Service (our client and server will run in the same machine, using named pipes to communicate).
I run the wizard, deleted the WFC Service Application and created two console apps, one called Server and another called Client. The server is pretty simple:
I then run the Server, and added a Service Reference in my Client, autogenerating everything thanks to the metadata. My Client can connect to the Server and add simple entities like this.
And things work fine. But, I have no idea on how to add new Sites to the Project. I have tried this approach:
And I get a FaultException in the CreateProject line saying this:
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:project. The InnerException message was 'The use of type 'OpenAccessTestProject.Project' as a get-only collection is not supported with NetDataContractSerializer. Consider marking the type with the CollectionDataContractAttribute attribute or the SerializableAttribute attribute or adding a setter to the property.'. Please see InnerException for more details.
(nothing on the Inner Exception)
Then I tried this:
And I got the same exception with the same message in the CreateSite line.
I tried also this:
And got this exception in the CreateProject line:
There was an error while trying to serialize parameter http://tempuri.org/:project. The InnerException message was 'Object graph for type 'Client35.TestDataService.Site' contains cycles and cannot be serialized if reference tracking is disabled.'. Please see InnerException for more details.
Which makes me wonder what happened as the Service interface is marked with the attribute CyclesReferencesAware(true).
I have been checking and it seems the problem is because the entities generated by the Domain Model designer only have a get accesor in the properties for the collections that represents relationships, but I haven't found a way to make the designer generate a set accesor (apart from editing the templates), nor I have any clue if that's a good idea :S
So, my question is: any guidance on this subject? What is the OpenAccess way of solving this type of situation?
Regards,
Vicente
I'm evaluating OpenAccess as our ORM for a client-server scenario and I have some doubts on how things should be approached. I have a DB in SQlite with some tables, for this example I have a table called Projects and another called Sites. A Project can contain many Sites and a Site can only be part of a single Project. Both tables also have a Description field for adding text information.
I created a Class Library project where I created an OpenAccess Domain Model with my entities (I used attributes for the mappings).
Then I created a WCF Service Application (to get around the limitation of the Data Services Wizard when selecting projects). I told the wizard to generate the service on a new class library called Service. The Data Services Type is WCF EndPoints Service (our client and server will run in the same machine, using named pipes to communicate).
I run the wizard, deleted the WFC Service Application and created two console apps, one called Server and another called Client. The server is pretty simple:
namespace Server
{
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using Service;
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(DataService)))
{
var binding = new NetNamedPipeBinding();
string address = "net.pipe://localhost/DataService";
ServiceEndpoint endPoint = host.AddServiceEndpoint(typeof(IDataService), binding, address);
ServiceMetadataBehavior metadataBehavior = host.Description.Behaviors.Find<
ServiceMetadataBehavior
>();
if (metadataBehavior == null)
{
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = new Uri("http://localhost:8888");
host.Description.Behaviors.Add(metadataBehavior);
}
host.Open();
Console.WriteLine("Server running. Press ENTER to end it.");
Console.ReadLine();
}
}
}
}
I then run the Server, and added a Service Reference in my Client, autogenerating everything thanks to the metadata. My Client can connect to the Server and add simple entities like this.
DataServiceClient client =
new
DataServiceClient(
new
NetNamedPipeBinding(),
new
EndpointAddress(
"net.pipe://localhost/DataService"
));
client.Open();
// Create things
Project p =
new
Project();
p.Description =
"Added by the client"
;
string
result = client.CreateProject(p);
And things work fine. But, I have no idea on how to add new Sites to the Project. I have tried this approach:
Project p =
new
Project();
p.Description =
"Added by the client"
;
Site s =
new
Site();
s.Description =
"Added by the client too"
;
p.Sites =
new
List<Site>();
p.Sites.Add(s);
string
result = client.CreateProject(p);
And I get a FaultException in the CreateProject line saying this:
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:project. The InnerException message was 'The use of type 'OpenAccessTestProject.Project' as a get-only collection is not supported with NetDataContractSerializer. Consider marking the type with the CollectionDataContractAttribute attribute or the SerializableAttribute attribute or adding a setter to the property.'. Please see InnerException for more details.
(nothing on the Inner Exception)
Then I tried this:
Project p =
new
Project();
p.Description =
"Added by the client"
;
string
result = client.CreateProject(p);
Project p2 = client.ReadProject(result);
Site s =
new
Site();
s.Description =
"Added by the client too"
;
s.Project = p2;
string
result2 = client.CreateSite(s);
And I got the same exception with the same message in the CreateSite line.
I tried also this:
Project p =
new
Project();
p.Description =
"Added by the client"
;
Site s =
new
Site();
s.Description =
"Added by the client too"
;
p.Sites =
new
List<Site>();
p.Sites.Add(s);
s.Project = p;
string
result = client.CreateProject(p);
And got this exception in the CreateProject line:
There was an error while trying to serialize parameter http://tempuri.org/:project. The InnerException message was 'Object graph for type 'Client35.TestDataService.Site' contains cycles and cannot be serialized if reference tracking is disabled.'. Please see InnerException for more details.
Which makes me wonder what happened as the Service interface is marked with the attribute CyclesReferencesAware(true).
I have been checking and it seems the problem is because the entities generated by the Domain Model designer only have a get accesor in the properties for the collections that represents relationships, but I haven't found a way to make the designer generate a set accesor (apart from editing the templates), nor I have any clue if that's a good idea :S
So, my question is: any guidance on this subject? What is the OpenAccess way of solving this type of situation?
Regards,
Vicente