Ria services - children collection is not visible in Generated Code on UI layer

Posts   
 
    
Posts: 19
Joined: 11-Jan-2010
# Posted on: 29-Dec-2011 21:40:48   

Hello everybody,

There are 2 tables: Equipment (EquipId - PK) & Meter (MeterId = PK, EquipId - FK). In LLBLGen Pro Designer (v. 3.1 Final, released on Sep 30th 2011) on Edit tab Attributes, Code gen.info section of: 1) Equipment entity: when I select Element: Meters, I have empty Default attributes inherited from project properties, but in Attribute Definition I have Browsable($true) System.ComponentModel.DataAnnotations.Composition System.ComponentModel.DataAnnotations.CompositionAttribute 2) Meter Entity: under selected Equipment element I have: Browsable($true) System.ComponentModel.DataAnnotations.Composition

In DomainService Class I have the following code.

<Query(HasSideEffects:=True)> Public Function GetEquipmentExternalId(Optional ByVal ls As List(Of String) = Nothing) As IQueryable(Of EquipmentExternalIdEntity)

  Dim q = From r In New LinqMetaData(CreateDataAccessAdapter()).EquipmentExternalId.WithPath(
      New PathEdge(Of EquipmentExternalIdEntity)(EquipmentExternalIdEntity.PrefetchPathEquipment,
      New PathEdge(Of EquipmentEntity)(EquipmentEntity.PrefetchPathMeters)))
    Select r

  If ls IsNot Nothing Then
    q = From r In q Where ls.Contains(r.ExternalId)
  End If

  Return q
 End Function

When I debug "q" I can see Meters collection for EquipmentEntity, but on UI layer it's empty.

What should I do to make it visible?

Thank you, G.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 30-Dec-2011 10:29:51   
Posts: 19
Joined: 11-Jan-2010
# Posted on: 30-Dec-2011 17:57:44   

I do not want to apply IncludeAttributes to all entities therefore I have not added it on project level. In LLBLGen designer for Equipment entity, Meters element, in Code gen.info / Attribute definition section I have: System.ComponentModel.DataAnnotations.CompositionAttribute System.ServiceModel.DomainServices.Server.IncludeAttribute

In InfoFinderDomainService class I added (reformatted for clarity -- daelmo)

<Query(IsDefault:=True)>
Public Function GetEquipment() As IQueryable(Of EquipmentEntity)
    If VerifyAuth() Then
      Dim patharray() As PathEdge(Of EquipmentEntity) = 
     {
          New PathEdge(Of EquipmentEntity)(EquipmentEntity.PrefetchPathExternalIds),
          New PathEdge(Of EquipmentEntity)(EquipmentEntity.PrefetchPathEquipmentEvents),
          New PathEdge(Of EquipmentEntity)(EquipmentEntity.PrefetchPathMeters)
      }
    
      Dim l = New LinqMetaData(CreateDataAccessAdapter())
      Dim q = l.Equipment.WithPath(patharray)
      Return q
    Else
      Return Nothing
    End If
End Function

On my ViewModel I added a call to test it:

'test
Dim eqid As Integer = xr.Equipment.EquipmentId
Dim qq = From o In context.GetEquipmentQuery Where o.EquipmentId = eqid Select o

Dim equip = New QueryableDomainServiceCollectionView(Of EquipmentEntity)(context, qq)
equip.Load()
equip.AutoLoad = True
'end of test

When I run it, I get Equipment entity, but Meters collection is still empty. Instead of it I see: Exception of type 'System.Linq.SystemCore_EnumerableDebugViewEmptyException' was thrown.

What I'm missing?

Thank you, G.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 31-Dec-2011 00:26:46   

gdolinskaya wrote:

When I run it, I get Equipment entity, but Meters collection is still empty. Instead of it I see: Exception of type 'System.Linq.SystemCore_EnumerableDebugViewEmptyException' was thrown.

Please post the exact exception message and stack trace for that exception.

David Elizondo | LLBLGen Support Team
Posts: 19
Joined: 11-Jan-2010
# Posted on: 03-Jan-2012 17:51:40   

Thank you for your response.

I need to handle another stuff right now therefore I would like to put aside this discussion for a few days.

As I mentioned before on a client side there is empty Meters collection in EquipmentEntity object and I can see the following info in Watch window (if it helps):

_meters:
Value = Nothing Type = System.ServiceModel.DomainServices.Client.EntityCollection(Of Transfinder.DomainModel.EntityClasses.MeterEntity)

Meters.Results:

  • Meters {MeterEntity} System.ServiceModel.DomainServices.Client.EntityCollection(Of Transfinder.DomainModel.EntityClasses.MeterEntity) Count 0 Integer
  • Results Expanding will process the collection <enumerable type> _HResult -2146233088 Integer _message Nothing String
  • Data {System.Collections.ListDictionaryInternal} System.Collections.IDictionary
  • System.Collections.ListDictionaryInternal {System.Collections.ListDictionaryInternal} System.Collections.ListDictionaryInternal Count 0 Integer IsFixedSize False Boolean IsReadOnly False Boolean IsSynchronized False Boolean Item In order to evaluate an indexed property, the property must be qualified and the arguments must be explicitly supplied by the user. Object
  • Keys {System.Collections.ListDictionaryInternal.NodeKeyValueCollection} System.Collections.ICollection SyncRoot {Object} Object
  • Values {System.Collections.ListDictionaryInternal.NodeKeyValueCollection} System.Collections.ICollection Empty "Enumeration yielded no results" String HelpLink Nothing String HResult -2146233088 Integer InnerException Nothing System.Exception Message "Exception of type 'System.Linq.SystemCore_EnumerableDebugViewEmptyException' was thrown." String Source "System.Core" String StackTrace " at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()" String

Thanks again, G.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 03-Jan-2012 20:23:43   

I see you prefetch other collections too. Do you get ExternalIds and EquipmentEvents?

David Elizondo | LLBLGen Support Team
Posts: 19
Joined: 11-Jan-2010
# Posted on: 04-Jan-2012 17:10:46   

Yes, I do.

I've created a sample code to track down the problem and I have the same issue. There are 3 tables, referenced to each other : Equipment (EquipId - PK) & Meter (MeterId = PK, EquipId - FK) & EquipmentEvent (EquipEventId - PK, EquipId - FK, MeterId - FK).

InfoFinderDomainService: <Query(IsDefault:=True)> Public Function GetEquipment() As IQueryable(Of EquipmentEntity)

    Dim patharray() As PathEdge(Of EquipmentEntity) = {New PathEdge(Of EquipmentEntity)(EquipmentEntity.PrefetchPathMeters,
                                                      New PathEdge(Of MeterEntity)(MeterEntity.PrefetchPathEquipmentEvents)),
                                                        New PathEdge(Of EquipmentEntity)(EquipmentEntity.PrefetchPathEquipmentEvents),
                                                      New PathEdge(Of EquipmentEntity)(EquipmentEntity.PrefetchPathExternalIds)}

    Dim l = New LinqMetaData(CreateDataAccessAdapter())
    Dim q = l.Equipment.WithPath(patharray)
    Return q

End Function

In Watch window: each EquipmentEntity in q has records in Meters collection, records in EquipmentEvents collection, but each EquipmentEvent has Meter = Nothing, MeterId = valid number.

On UI in ViewModel I put code: Dim eqid As Integer = xr.EquipmentId context.Load(context.GetEquipmentQuery) Dim eq = context.EquipmentEntities.Where(Function(f) f.EquipmentId = eqid)

In Watch window: eq (In-Memory Query) = EquipmentEntity which has Meters = Nothing EquipmentEvents = valid collection, but each EquipmentEvent.Meter = Nothing, EquipmentEvent.MeterId = valid number.

In LLBLGen I made some changes. Now in Code gen.info, Attributes tab: Equipment - EquipmentEvents & Equipment - Meters there are no attributes, I have empty space.

EquipmentEvent - Equipmet & EquipmentEvent - Meter & Meter - Equipment have the same Attribute definition: Browsable($true) Inherit = checked; System.ComponentModel.DataAnnotations.Composition Inherit = not checked.

Meter - EquipmentEvents - empty tab;

What do I have to do to make Meters collection visible for Equipment entity on client side???

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 05-Jan-2012 04:19:49   

gdolinskaya wrote:

In Watch window: each EquipmentEntity in q has records in Meters collection, records in EquipmentEvents collection, but each EquipmentEvent has Meter = Nothing, MeterId = valid number.

...

On UI in ViewModel I put code: Dim eqid As Integer = xr.EquipmentId context.Load(context.GetEquipmentQuery) Dim eq = context.EquipmentEntities.Where(Function(f) f.EquipmentId = eqid)

In Watch window: eq (In-Memory Query) = EquipmentEntity which has Meters = Nothing EquipmentEvents = valid collection, but each EquipmentEvent.Meter = Nothing, EquipmentEvent.MeterId = valid number.

So if I understand correctly you have two problems: 1. You prefetch EquipmentEntity.PrefetchPathMeters and it's ok (pupulated) but when it arrives to the ViewModel that collection is empty.

  1. You expect that each EquipmentEvent prefetched entity has the Meter navigator pupulated as well.

For (1) the only difference between EquipmentEntity.PrefetchPathMeters and the other prefethes is that you are nesting another level (MeterEntity.PrefetchPathEquipmentEvents). The other thing I see is that you are using incorrectly the generic part on the prefetch. Right now your code looks like (a little reformatted):

Dim patharray() As PathEdge(Of EquipmentEntity) = 
{
    New PathEdge(Of EquipmentEntity) 
    (
        EquipmentEntity.PrefetchPathMeters,
            New PathEdge(Of MeterEntity)(MeterEntity.PrefetchPathEquipmentEvents)
    ),
    
    New PathEdge(Of EquipmentEntity)(EquipmentEntity.PrefetchPathEquipmentEvents),
    New PathEdge(Of EquipmentEntity)(EquipmentEntity.PrefetchPathExternalIds)
}

and it should be

Dim q = l.Equipment.WithPath( _
    New PathEdge(Of MeterEntity)( _
        EquipmentEntity.PrefetchPathMeters,
        New PathEdge(Of EquipmentEventEntity)(MeterEntity.PrefetchPathEquipmentEvents)),
    New PathEdge(Of EquipmentEventEntity)(EquipmentEntity.PrefetchPathEquipmentEvents),
    New PathEdge(Of ExternalIdEntity)(EquipmentEntity.PrefetchPathExternalIds))

as you see the type of the prefetch object should be the type of the end node. See the examples. I don't know if this would make any difference but please give it a try.

About (2), you have to add another level to EquipmentEntity.PrefetchPathEquipmentEvents to be able to prefetch its related Meter. Something like:

Dim q = l.Equipment.WithPath( _
    New PathEdge(Of MeterEntity)( _
        EquipmentEntity.PrefetchPathMeters,
        New PathEdge(Of EquipmentEventEntity)(MeterEntity.PrefetchPathEquipmentEvents)),
    New PathEdge(Of EquipmentEventEntity)( _
        EquipmentEntity.PrefetchPathEquipmentEvents,
        New PathEdge(Of MeterEntity)(EquipmentEventEntity.PrefetchPathMeter)),
    New PathEdge(Of ExternalIdEntity)(EquipmentEntity.PrefetchPathExternalIds))

Other than that, I don't have any idea of the reason for that behavior. I tried a similar test with Northwind and everything seems to be ok. Could you reproduce that behavior in Northwind?

David Elizondo | LLBLGen Support Team