Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

LINQ/PLINQO/WCF Nightmare

Posted on 2009-07-11
3
Medium Priority
?
886 Views
Last Modified: 2013-11-11
Any WCF/LINQ experts out there?  I'm having a heck of a time getting my relational data to pass through WCF.

First off, I tried all of this through straight LINQ to SQL and was getting some error regarding a circular reference, which I found puzzling as I didn't see a circular reference in my db.  After fighting with LINQ to SQL I moved on to trying PLINQO and the circular error went away, however the nested Lists of entities won't transmit properly.

I have several tables in my db but the 2 currently in question are CustomersVendors and Addresses.  The addresses are linked to the CustomersVendors table via listID <--- customerVendorListID and the 2 columns are identical.  When I request a CustomerVendor by listID I expect to get back all of their details including a List(Of Addresses).  Upon tracing the results I see the query works just fine and I do in fact see the Addresses in the CustomersVendors entity.  The problem is, once this data is sent out via WCF the Addresses entity inside of the CustomerVendor is NULL.  Tracelogs on the server side of my app don't show the addresses so they are obviously never leaving the server.  I'm guessing it's a serialization issue but I'm at the end of my rope trying to find the cause.  I sure hope someone out there can figure this one out.

vs2008 SP1 (VB.NET)
.NET 3.5 SP1
Vista Business SP3
PLINQO v3.0.687
0
Comment
Question by:thesnoman
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 
LVL 64

Expert Comment

by:Fernando Soto
ID: 24830397
Hi thesnoman;

I am not a WCF expert but you seem to be on the right track about serialization. Linq by default sets the Serialization Mode to none. In WCF applications it should be set to Unidirectional which will allow the child records to come across as well. To set the DataContext for this setting do the following.

1. Open the OR/M designer and right click on the design surface where there are NO tables.
2. Select Properties in the context menu.
3. Select the Serialization Mode property and in its combo box select Unidirectional.

Hopefully this will do it.

Fernando
0
 

Author Comment

by:thesnoman
ID: 24830985
Thanks for the reply Fernando,

I've actually tried that and it didn't help.  I've not found a true solution yet so for now what I've done is remove all relationships from the db and create wrappers for sending the data, as shown in the code snippet.  This works fine but it adds a fair amount of code and time to parse.  I'm not yet sure what I'm going to run into for saving but I'm sure it's going to be a lot more work.  It's a shame when something that's supposed to save us time costs us a lot more.  If you or anyone else has anymore ideas please pass them along as I'd be glad to hear them.


Custom Wrapper:
 
<DataContract()> _
Public Class twCustomerVendor
    Private _customerVendor As CustomersVendor
    Private _addresses As List(Of Address)
    Private _contacts As List(Of Contact)
 
    <DataMember()> _
    Public Property CustomerVendor() As CustomersVendor
        Get
            Return Me._customerVendor
        End Get
        Set(ByVal value As CustomersVendor)
            Me._customerVendor = value
        End Set
    End Property
 
    <DataMember()> _
Public Property Addresses() As List(Of Address)
        Get
            Return Me._addresses
        End Get
        Set(ByVal value As List(Of Address))
            Me._addresses = value
        End Set
    End Property
 
    <DataMember()> _
Public Property Contacts() As List(Of Contact)
        Get
            Return Me._contacts
        End Get
        Set(ByVal value As List(Of Contact))
            Me._contacts = value
        End Set
    End Property
End Class
 
 
Then I populate it as follows:
 
Public Function GetCustomerVendor(ByVal ListID As Integer) As twCustomerVendor
    Dim Context As New OxionIt2DataContext
    Dim ret As New twCustomerVendor
 
    ret.CustomerVendor = (From cv In Context.CustomersVendor _
                          Where cv.ListID = ListID _
                          Select cv).SingleOrDefault
 
    ret.Addresses = (From a In Context.Address _
                     Where a.CustomerVendorListID = ret.CustomerVendor.ListID _
                     Select a).ToList
 
    ret.Contacts = (From c In Context.Contact _
                    Where c.CustomerVendorListID = ret.CustomerVendor.ListID _
                    Select c).ToList
 
    Return ret
 
End Function

Open in new window

0
 

Accepted Solution

by:
thesnoman earned 0 total points
ID: 24835817
For future reference I found the solution.  It is not a WCF serialization issue as first suspected rather it part of LINQ's lazy loading technique.  While I knew this existed I did not know that at the time of loading the parent it does not actually load all the related children as I would have expected.  There is a way to get around this issue and it involves LINQ's "DataLoadOptions" command.  This forces LINQ to load all the related info when the parent record is loaded.  This can also be a good thing to minimize the number of queries made against the database.  

Here is a sample of my code in VB that may save someone else hours/days of research, troubleshooting, and heartache.  Notice DataLoadOptions and each line specifying LoadWith with a regular expression enclosed (something I don't know much about) identifying each child (related table) object to load.  Obvioiusly, depending on what data you wanted to load at the time you could include a limited number of children but in my case I wanted all relational data to be populated and sent to the WCF client for viewing/editing.
 
Hope this helps someone else out.

P.S. For what it's worth, I am using the PLINQO templates as mentioned earlier to setup, maintain and extend my LINQ entities and the dbml file and sp far I like it.  If you are interested in it you can do a Google search PLINQO and CodeSmith, the application that actually runs it.  One very nice feature, when you change your database schema you can actually refresh the dbml file and entities by regenerating the PLINQO output.  So far this has saved me a lot of time and it sets up a very clean project.


        Public Function GetCustomerVendor(ByVal ListID As Integer) As CommWrapper
            Dim Context As New DataContext
            Dim ret As New CommWrapper
            Dim dlOptions = New DataLoadOptions()
 
            ' Causes the Customer/Vendor to actively load the related data lists.  One required for each relational table.
            dlOptions.LoadWith(Of CustomersVendor)(Function(cv) cv.CustomerVendorAddressList)
            dlOptions.LoadWith(Of CustomersVendor)(Function(cv) cv.CustomerVendorCommissionList)
            dlOptions.LoadWith(Of CustomersVendor)(Function(cv) cv.CustomerVendorContactList)
            dlOptions.LoadWith(Of CustomersVendor)(Function(cv) cv.CustomerVendorEmailAddressList)
            dlOptions.LoadWith(Of CustomersVendor)(Function(cv) cv.CustomerVendorPhoneNumberList)
 
            Context.LoadOptions = dlOptions
 
            ret.CustomerVendorList = (From cv In Context.CustomersVendor _
                                  Where cv.ListID = ListID _
                                  Select cv).ToList
 
            Return ret
        End Function

Open in new window

0

Featured Post

Tech or Treat! - Giveaway

Submit an article about your scariest tech experience—and the solution—and you’ll be automatically entered to win one of 4 fantastic tech gadgets.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses

610 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question