You just hit the exact same problem we had in our system (also based on WCF) for about two years ago.
We also use OpenAccess as ORM.
The problem is the lazy loading of OA and the default DataContractSerializer used on your DataContract classes that forms your contract for your WCF service. I am guessing you have decorated your OA persistent model classes with the DataContract attribute also, right? So, you end up serializing persistent instance over the wire when your WCF service is called.. right?
What happens is that the DataContractSerializer (the "thing" that actually transforms your class to xml to be sent on the wire and vice versa) performs a read (get property) on all properties of your DataContract class... thus invoking lazy loading for properties that have not yet been loaded (it totally ignores the fetchplan - since it has no idea of it - only OA knows about it)
Another thing, the default behaviour of the DataContractSerializer is to embed every object.. even though it is the same instance (compared to the Id) - in other words: It has no idea of "object identity".
Anyway... there are two solutions to your problem. A quick one .. and a more time consuming one
The quick one (only works if using .NET 3.5SP1)
Pass the "IsReference=true" when decorating your DataContract class with the DataContract attribute.
This will bring "object identity" to the on-the-wire XML format used by the DataContractSerializer. Thus, the serializer will use references to the same instance instead of embedding them again and again.. Thus, no more cycles in m:n relations.
But remember... everything that can be reached (has a public property) and is decorated with the DataMember attribute is serialized by the DataContractSerializer... - everything..!.. I am mentioning this because typically you would design you persistent classes to be highly navigational in nature.. and high navigation equals a lot that can be reached by the serializer.
See this example
for an very good example of how to do it.
The more time consuming one
Add an addiotional mapping layer that sits between your persistent model classes and your DataContract classes.. for example you have one persistent class called Customer in Model assembly and you have one DataContract class called Customer in the DataContracts assembly. Upon a WCF service request (going in) you have a "mapping layer" that maps from the DataContract classes to the persistent model classes (if something needs to be persisted) and vice versa (when sending the response to the client)
By doing so you are separating you persistent model from the one you expose to "the outer world" in your WCF services.
I don't know what method fits in your scenario.. as always .. it depends... :-) We did "the more time consuming one" in our system, mostly because a) We have more client types (consumer types) accessing the same services (with different security rights) and b) We did not want to expose our "full" persistent model to the world as this tends to be the case (when doing the quick one) over time and the system grows..
Hope this post, shed some light on your issues...and hope to help