locked
Objects not bound with multiple Expand statements RRS feed

  • Question

  • Hi,

    I have the following data (reduced).
    Session:
       SessionID,
       Title
    Tags:
        TagID,
        Description
    (Just to bind):
    Session2Tags:
        TagID,
        SessionID

    With EntityFramwork I get the following classes:
    Session
       Title (String)
        Tags (Collection)
    Tags
        Description (String)
        Sessions(Collection)

    The thing - a session could belong to multiple "categories" (Tags) - and under one Category I can have multiple sessions.

    My app displays a combobox with the possible Tags.
    When I select a Tag than I fill a listbox with the Sessions under this tag.

    This works fine with
    combobox1.DataContext=ctx.Tags.Expand("Session");

    I can do the same with EF (without data services) in the form
    combobox1.DataContext=ctx.Tags.Include("Session");

    So now I wanted to expand the thing a bit and provide a third combobox which shows the tags under which a session is registered.
    With EF I do:
    combobox1.DataContext=ctx.Tags.Include("Session").Include("Session.Tags");
    And it works fine!!!

    Now I tried the same with data services in this way:
    combobox1.DataContext=ctx.Tags.Expand("Session").Expand("Session/Tags");

    Now the things work only "half the way".

    First impression:
    I have a (top listed) tag "All" - which tags every session.
    In this situation only the first tag in the combobox has "Sessions" entries.
    All other have a valid Sessions object - but Count==0.

    Second impression:
    I placed the "All" tag backwards in Sorting (calling it XAll).
    Not I get some Sessions bound to the Tags - but it looks as if the are bound only until all kind of Tags have been used in Sessions.Tags.

    Example:
    Tags available: Kind1, Kind2, Kind3
    Session1 - Tags: Kind1
    Session2 - Tags: Kind2, Kind3
    Session3 - Tags: Kind1, Kind3
    Session4 - Tags: Kind2

    In this situation I get Sessions for the Tags Kind1 and Kind2.
    Sessions is not bound to Kind3 (it seems as this has something to do with the fact that Kind3 already exists in a Session under Kind2).
    So the Tags look like this:
    Tag_Kind1: Sessions (1,3)
    Tag_Kind2: Sessions(2,4)
    Tag_Kind3: Sessions(Count==0)

    If I have the "All_Tag" on Top it would look like this.
    Tag_Kind_ALL: Sessions (1,2,3,4)
    Tag_Kind1: Sessions(Count==0)
    Tag_Kind2: Sessions(Count==0)
    Tag_Kind3: Sessions(Count==0)


    By watching the service (giving the URI the combobox1.DataContext=ctx.Tags.Expand("Session").Expand("Session/Tags"); statement produces I get the data like it should be.
    It looks like
    http://localhost:2128/XDS.svc/Tags()?$expand=Sessions,Sessions/Tags
    And it provides me with the correct data.

    So it seems as if the binding is broken - or if it is some kind of "distinct" binding where I have to change something.
    The data is OK - it works well with local Entity Framework.
    It also works with the service - as long as I expand only one "subelement" (combobox1.DataContext=ctx.Tags.Expand("Session");

    But it fails as soon as I expand the second element.

    Any help would be great!!

    Manfred
    Tuesday, March 24, 2009 8:30 PM

All replies

  • Follow UP.

    It seems as this has something to do with execution time or so.
    I tried around a bit more and found

    //siE==my context  
    siE.MergeOption = System.Data.Services.Client.MergeOption.AppendOnly;  
    var xR = from y in siE.Tags.Expand("Sessions").Expand("Sessions/Tags")  
             select y;  
    cbTags.DataContext = xR; //fails  
     
    This fails also:
    var xR = from y in siE.Tags.Expand("Sessions")  
             select y;  
     
    foreach (pdcDataSVC.Tags tG in xR) {  
        foreach (pdcDataSVC.Sessions sI in tG.Sessions) {  
            siE.LoadProperty(sI, "Tags");  
        }  
    }  
    cbTags.DataContext = xR;  
     
    STRANGE - but this works:
    var xR = from y in siE.Tags.Expand("Sessions")  
             select y;  
     
    foreach (pdcDataSVC.Tags tG in xR) { //just to force evaluation  
    }  
    foreach (pdcDataSVC.Tags tG in xR) {  
        foreach (pdcDataSVC.Sessions sI in tG.Sessions) {  
            siE.LoadProperty(sI, "Tags");  
        }  
    }  
    cbTags.DataContext = xR;  
     
    This is slowest - but works also:
    var xR = from y in siE.Tags  
             select y;  
     
    foreach (pdcDataSVC.Tags tG in xR) {  
        siE.LoadProperty(tG,"Sessions");  
        foreach (pdcDataSVC.Sessions sI in tG.Sessions) {  
            siE.LoadProperty(sI, "Tags");  
        }  
    }  
    cbTags.DataContext = xR;  
     
    By the way - the last form fails also when tags contain dots!!!
    I get an error telling me that the call failed.
    The result was a 404 (not found) for the query
    Tags('ADO.NET')/Sessions()
    When I try this by hand it also fails!!!

    I call /Tags - and get back one which tells me it's URI would be /Tags('ADO.NET')
    But when I add this to the addressline I get a 404.
    If I change the data to ADO_NET it works!!!

    Thinks get more problematic (and confusing) the more I try...

    Manfred
    Tuesday, March 24, 2009 9:35 PM
  • Can you try setting ctx.MergeOption to MergeOption.OverwriteChanges. The default behavior is AppendOnly, and in that merge option, we don't try to set up a relationship which is already seen.

    We are looking into this and trying to figure out a way to make default option work better.

    http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/thread/abbe0639-5330-4405-a5db-6990aa5c073f - look at the bottom of the thread, i have tried to explain how various merge options work.

    Thanks
    Pratik
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Wednesday, March 25, 2009 5:55 PM
    Moderator
  • Hi,

    if I do it like this:
        siE.MergeOption = System.Data.Services.Client.MergeOption.OverwriteChanges;  
                    cbTags.DataContext =siE.Tags.Expand("Sessions").Expand("Sessions/Tags");  
                 
    I get an error "an element with the key already exists".

    What works now is
                    siE.MergeOption = System.Data.Services.Client.MergeOption.OverwriteChanges;  
                    var xR = from y in siE.Tags.Expand("Sessions") //.Expand("Sessions/Tags")  
                             select y;  
     
                    foreach (pdcDataSVC.Tags tG in xR) {  
                        foreach (pdcDataSVC.Sessions sI in tG.Sessions) {  
                            siE.LoadProperty(sI, "Tags");  
                        }  
                    }  
    ... 
    This did not work before without having the "empty loop".

    But it is still kind of strange whats going on.
    Wednesday, March 25, 2009 9:06 PM