locked
Attributes and datasvcutil.exe RRS feed

  • Question

  • Hi guys,

     

    This is more a request not an issue.

     

    Can you please add an attribute to any 'complex type' properties on object when generating client classes using generation tool (datasvcutil.exe) .

     

    I hav a generic repository object and I want to use reflection to get all fields attributed as 'complex types' to build object tree when i need to persist data.

    Eg. newConsumer.Gender = genderItem

     

    //used for saving entity

    repository.SaveEntity<Consumer>(newConsumer, new AsyncCallback(onSaveConsumer));

     

    //Repository object SaveEntity explores Type <Consumer > in this case, for any fields attributed as complex types and builds 'relationships' that are needed.

     

    Eg.

    foreach (var item in attributedFields)

    {

    //Complex Object Name

    string complexObjectName = item.GetType().Name;

    // ComplexObjectSet Name Eg. GenderSet

    string existingEntitySet = complexObjectName + "Set";

    // Attach to current Context

    _dataServiceContext.AttachTo(existingEntitySet, item);

    // Create Link -- ConsumerSet --

    _dataServiceContext.SetLink(trackingEntity, complexObjectName, item);

    }

     

     

    This will save me from re-adding attributes when i need to regenerated proxy classes.

     

    Thanks

     -Rustin

     

     

    Tuesday, October 14, 2008 3:38 PM

Answers

  • Can you just do a $metadata and get the xml file and load the metadata? EntityFramework has public api's that loads the given xml file and gives you nice metadata API's to figure out the metadata. Here's the code snippet:

     

    Code Snippet

     

    //Get metadata from the service

    new WebClient().DownloadFile("http://pratikp3/Repro1/CustomDataService.svc/$metadata", @"c:\metadata.xml");

     

    // Load metadata xml file into a xml document

    XmlNameTable nt = new NameTable();

    XmlNamespaceManager namespaceMgr = new XmlNamespaceManager(nt);

    namespaceMgr.AddNamespace("edmx", "http://schemas.microsoft.com/ado/2007/06/edmx");

    namespaceMgr.AddNamespace("dataweb", "http://schemas.microsoft.com/ado/2007/08/dataservices");

    namespaceMgr.AddNamespace("edm1", "http://schemas.microsoft.com/ado/2006/05/edm");

    namespaceMgr.AddNamespace("edm2", "http://schemas.microsoft.com/ado/2007/05/edm");

    XmlDocument document = new XmlDocument(nt);

    document.Load(@"c:\metadata.xml");

     

    // Get the schema nodes from the xml document so that we can load it in edm item collection

    XmlNodeList nodeList = document.SelectNodes("//edm1:Schema", namespaceMgr);

    List<XmlReader> readers = new List<XmlReader>();

    for (int i = 0; i < nodeList.Count; i++)

    {

        readers.Add(nodeList[i].CreateNavigator().ReadSubtree());

    }

    nodeList = document.SelectNodes("//edm2:Schema", namespaceMgr);

    for (int i = 0; i < nodeList.Count; i++)

    {

        readers.Add(nodeList[i].CreateNavigator().ReadSubtree());

    }

    EdmItemCollection metadataCollection = new EdmItemCollection(readers);

     

    // Add code here to query metadata

    EntityType entityType = metadataCollection.GetItem<EntityType>("Foo.Customer");

    foreach (EdmMember property in entityType.Properties)

    {

        if (property.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType)

        {

            // do something;

        }

    }

     

     

    If you do this, hopefully you won't have to do any reflection and know the astoria rules.

     

    Hope this helps.

    Thanks

    Pratik

     

    Tuesday, October 14, 2008 6:08 PM
    Moderator