1

I've got a SL4 / WCF RIA Services / EF 4 application. I'm having trouble getting my Included entity into my SL4 data context.

In the server side service portion of the application, this is my method:

 [Query(IsDefault = true)]
    public IQueryable<ToolingGroup> GetToolingGroups()
    {
        var groups = this.ObjectContext.ToolingGroups.Include("MetaData").OrderBy(g => g.Name);
        return groups; //breakpoint set here
    }

I assigned it to the var groups to allow it to be inspected before the method returns. If I set a breakpoint before the method returns and add a line to my Watch window the MetaData is there:

groups.First().MetaData

When I let the method return and check it in the silverlight ui completed event MetaData is null.

void loadOperation_Completed(object sender, System.EventArgs e)
    {
        grid.ItemsSource = _toolingContext.ToolingGroups;
        UpdateUI(); //breakpoint set here
    }

When I do this in my watch window MetaData is null:

_toolingContext.ToolingGroups.First().MetaData

I checked to make sure the ToolingGroup returned by the call to .First() in both cases was the same entity and it was.

Why is MetaData lost (eg. null) between the service method and my ui method?

SOLUTION:

// The MetadataTypeAttribute identifies ToolingGroupMetadata as the class
// that carries additional metadata for the ToolingGroup class.
[MetadataTypeAttribute(typeof(ToolingGroup.ToolingGroupMetadata))]
public partial class ToolingGroup
{

    // This class allows you to attach custom attributes to properties
    // of the ToolingGroup class.
    //
    // For example, the following marks the Xyz property as a
    // required property and specifies the format for valid values:
    //    [Required]
    //    [RegularExpression("[A-Z][A-Za-z0-9]*")]
    //    [StringLength(32)]
    //    public string Xyz { get; set; }
    internal sealed class ToolingGroupMetadata
    {

        // Metadata classes are not meant to be instantiated.
        private ToolingGroupMetadata()
        {
        }

        public int Id { get; set; }

        [Include] // Added so MetaData gets serialized
        public MetaData MetaData { get; set; }

        public Nullable<int> MetaDataId { get; set; }

        public string Name { get; set; }

        public ToolingCategory ToolingCategory { get; set; }

        public int ToolingCategoryId { get; set; }

        public EntityCollection<ToolingType> ToolingTypes { get; set; }
    }
}
NullUserException
  • 77,975
  • 25
  • 199
  • 226
Brent Lamborn
  • 1,342
  • 3
  • 17
  • 37

1 Answers1

4

There are two layers at play here, EF and RIA Services. You've handled the EF part. Now you need to tell RIA services to include that property when it serializes your entities across the wire. In your metadata for the entity, add the [Include] attribute. Like this...

[MetadataType(typeof(ToolingGroup.MetaData)]
public partial class ToolingGroup {
    private class MetaData {

        // adding this attribute tells RIA services 
        // to also send this property across
        [Include]
        public MetaData MetaData { get; set; }
    }
}

It's a bad coincidence that your type is called "Metadata", the ToolingGroup.MetaData class is the metadata that RIA services uses.

Matt Greer
  • 57,161
  • 16
  • 118
  • 122
  • 1
    it's not mandatory to name the "Metadata" class `Metadata`! you can freely name it as you want since it's going to be set in the `MetadataTypeAttribute` :) – AbdouMoumen Mar 16 '11 at 21:50
  • Yes I noticed that MetaData was a bad choice when naming my table - after the fact of course. However - I am not seeing where to add the [Include] attribute. – Brent Lamborn Mar 16 '11 at 21:56
  • Can you take a look at this screenshot and see if I am in the right place to add the attribute? http://img855.imageshack.us/i/include.png/ Otherwise I don't see any code similar to your sample in my solution. – Brent Lamborn Mar 16 '11 at 22:01
  • No that is the generated code. In your web project, just add a file named ToolingGroup.metadata.cs (or anything you want, that is just the convention), then add the code I have above in my answer. This blog post goes into details on metadata classes: http://www.silverlightshow.net/items/WCF-RIA-Services-Part-5-Metadata-and-Shared-Classes.aspx – Matt Greer Mar 16 '11 at 22:11
  • Thanks! I had conflicts when adding that code but it allowed me to find the already existing class and so I added the [Include] attribute there. Updated my original post with the corrected code so others can see. – Brent Lamborn Mar 17 '11 at 15:56