none
WCF RIA Service - Hierarchical Display

    Question

  • I'm trying to understand how to display hierarchical data.  I have the following classes:

        Public Class PalParent
            <Key> _
            Public Property Id As Integer
            Public Property EmailAddress As String
            Public Property LastName As String
            Public Property FirstName As String
            <Association("PalParentListStudents", "Id", "ParentId", IsForeignKey:=False)> _
            Public Property PalListStudents As New List(Of PalListStudent)
    
            Public Sub AddStudent(child As PalListStudent)
                child.Parent = Me
                child.ParentId = Me.Id
                PalListStudents.Add(child)
            End Sub
    
        End Class
    
        Public Class PalListStudent
            <Key> _
            Public Property StudentId() As String
                Get
                    Return _StudentId
                End Get
                Set(value As String)
                    _StudentId = value
                End Set
            End Property
            Private _StudentId As Integer
            Public Property ParentId As Integer
            <Association("PalParentListStudents", "ParentId", "Id", IsForeignKey:=True)> _
            Public Property Parent As PalParent
    
            Public Property StudentName() As String
                Get
                    Return _StudentName
                End Get
                Set(value As String)
                    _StudentName = value
                End Set
            End Property
            Private _StudentName As String
    
            Public Property GradeLevel() As String
                Get
                    Return _GradeLevel
                End Get
                Set(value As String)
                    _GradeLevel = value
                End Set
            End Property
            Private _GradeLevel As String
    
            Public Property SchoolName() As String
                Get
                    Return _SchoolName
                End Get
                Set(value As String)
                    _SchoolName = value
                End Set
            End Property
            Private _SchoolName As String
        End Class
    

    Here are the routines to build the data.  The Fetch routines just do the sql calls:

            <Query(IsDefault:=True)> _
            Public Function GetPalParents() As IQueryable(Of PalParent)
                Dim PalParents = New List(Of PalParent)
    
                Dim ParentMaster = PalMgr.ParentMasterManager.FetchEntityPlus(PalMgr.ParentMasterManager.CreateBucket(PalMgr.ParentMasterManager.MyFields.EmailAddress = GetUserName()), , , PalMgr.ParentMasterManager.CreateBasicPrefetchList(MedfordSchoolDistrict.ParentInformation.ManagerClasses.ParentMasterManager.PrefetchItemEnum.ParentStudent))
    
                If ParentMaster Is Nothing OrElse ParentMaster.ParentStudent Is Nothing OrElse Not ParentMaster.ParentStudent.Any Then Return PalParents.AsQueryable ' Returns an empty query
    
                Dim NewPalParent = New PalParent With {.EmailAddress = ParentMaster.EmailAddress, .FirstName = ParentMaster.FirstName, .LastName = ParentMaster.LastName, .Id = ParentMaster.ParentId}
    
                Dim Students = SisMgr.StudentMstrManager.FetchEntityCollectionPlus(SisMgr.StudentMstrManager.CreateBucket(SisMgr.StudentMstrManager.MyFields.StudentId = ParentMaster.ParentStudent.Select(Function(X) X.StudentId).ToList))
    
                For Each Student In Students
                    Dim NewStudent = New PalListStudent With {.StudentId = Student.StudentId, .StudentName = Student.StudentNameFIL, .GradeLevel = Student.GradeLevel, .SchoolName = If(SharedSchoolNames.ContainsKey(Student.SchlId), SharedSchoolNames(Student.SchlId), "School: {0}".FormatString(Student.SchlId))}
                    NewPalParent.AddStudent(NewStudent)
                Next
    
                PalParents.Add(NewPalParent)
    
                Return PalParents.AsQueryable
            End Function
    
            <Query(IsDefault:=True)> _
            Public Function GetPalListStudents() As IQueryable(Of PalListStudent)
    
            End Function
    

    So I have a Parent and their associated students.  When I create the Data Source in LS it looks okay.  There is a PalParents and it has a PalListStudents within it.  

    I create a browse screen for PalParents and add the PalListStudents.  The PalParents displays but the associated PalListStudents do not show.  When I click on the PalParent then it goes to the GetPalListStudents routine.

    What I really want to do is simply show only the one PalParent for the current user (I don't even want an list or IQueryable of it) and the associated PalListStudents.

    Any help would be appreciated.

    Wednesday, August 27, 2014 8:13 PM

All replies

  • Can use the default query to return the full collection of PalListStudents, then make a second non-default query to get the students for the current user by passing in some kind of parameter representing the current user.  I use the email address as an example but you could use whatever you want.

    Public Function GetPalListStudentsByUser(CurrentUser As String) As IQueryable(Of PalListStudent)

    If (Not String.IsNullOrEmpty(CurrentUser) Then

    Return From q In GetPalListStudents()

    Where q.Parent.EmailAddress = CurrentUser

    Select q

    EndIf

    End Function

    Typing this by hand so be careful...

    Wednesday, August 27, 2014 8:54 PM
  • Thanks Hessc,

    I guess I can try that but I'm wondering if complex WCF RIA types work at all when using LS.  The WCF tables look correct but I can't seem to display them.  The program wants to go back to the server to get the data even though it should be there.

    Also, do I have that have everything sent as IQueryable?  What about single instances of an entry?

    Thanks

    Wednesday, August 27, 2014 9:20 PM
  •  

    Dave,

    I'm not sure about complex types.  When I use RIA services, I like to define each entity and any relationships (like you did).  I would remove the AddStudent method from the POCO just for troubleshooting and make two simple entities with a relationship defined, just until you get everything working.  Then make default parameterless queries for each entity that return the unfiltered basic collections.  You should be querying from an "ObjectContext" or whatever you call your underlying datasource connection.  You just want to fill up the POCOs with data just like the default unfiltered query you get from lightswitch when connecting to a sql server database.   Yes, you want the queries to return IQueryable(Of T).  Don't form a List(Of T) from your underlying datasource if you can help it, just query it and return a new entity AsQueryable.  You can then make non-default queries that accept parameters in the RIA Service.  These queries will show up like regular queries when you consume the RIA service in LightSwitch.  This works a lot Web Api (Get, Post, Put, Delete).  For single entities, use a non-default query and pass in an Id parameter.  Public Function GetPalListStudentsByUser(Id As Integer) As IQueryable(Of PalListStudent).  Query this off of the default query you defined for the entity.  When adding entities, once you add, you also need to call SaveChanges on the ObjectContext.  Check out this post (and other posts tagged as RIA Services at this site).




    • Edited by Hessc Thursday, August 28, 2014 1:29 AM
    Thursday, August 28, 2014 1:27 AM
  • Thanks Hessc,

    I will play around with it tomorrow and post my results.

    Thursday, August 28, 2014 2:08 AM
  • @Dave - I don't easily read/understand VB :) but LS will definitely not support the .AddStudent() method you have above.

    Regards, Xander. My Blog

    Thursday, August 28, 2014 2:27 AM
  • Hi Xander,

    The .AddStudent is just used in the Get routines and not called by LS at all.

    Thanks

    Thursday, August 28, 2014 3:41 AM
  • Even though it's not called by LS, it is in the class that LS will try to interpret into entity classes.  If it is not supported it could cause the entity to not show up in the designer or not behave properly.  I'm just speculating because I haven't tried it, but would definitely be interested in your results.  The only other thing I can think of that you might try is to remove the explicit get set on your properties.  You can use the generic syntax like: Public Property StudentName As String.  I'm not sure if that will make a difference but I know for sure that syntax will work.  Anything you can do to simplify the code will help your troubleshooting.
    Thursday, August 28, 2014 4:36 AM
  • Okay, I'll create a simplified version and see how that goes.
    Thursday, August 28, 2014 2:25 PM