locked
DataService publishes DataContexts it does not own RRS feed

  • Question

  • Hi,
    I am testing a new DataService:

    public class SalesOrderDataService : DataService<SalesOrderDataModel.SalesOrder_Entities>}}

        {
            // This method is called only once to initialize service-wide policies.
            public static void InitializeService(IDataServiceConfiguration config)
            {
                // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
                // For testing purposes use "*" to indicate all entity sets/service operations.
                // "*" should NOT be used in production systems.

                // Example for entity sets (this example uses "AllRead" which allows reads but not writes)
                config.SetEntitySetAccessRule("*", EntitySetRights.All);
    ...


    Surely this should publish all entities in the SalesOrder_Entities model and no other model??

    However I am getting entities from another model showing up as well, in this case my CreditorTransactionDataModel entities.

    I know I shouldn't use * except for testing, but surely * should be restricted to the Generic Type of the DataService.

    Cheers
    Simon
    Thursday, October 16, 2008 2:40 AM

Answers

  • Hi Pratik,

    $metadata sent to you by email. You see all the types defined and each correctly keep to their own namespace. However both the EntityContainers end up in the namespace of the DataService which is unexpected.




    As a work around I have add this code to the DataService


    public static void InitializeService(IDataServiceConfiguration config)
            {
               
                System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(false);
                System.Diagnostics.StackFrame sf = st.GetFrame(0);
                Type dataServiceObjectContextType = sf.GetMethod().DeclaringType.BaseType.GetGenericArguments()[0];
               
               
                foreach (PropertyInfo pi in dataServiceObjectContextType
                        .GetProperties().Where(p => p.PropertyType.BaseType == typeof(System.Data.Objects.ObjectQuery)))
                    config.SetEntitySetAccessRule(pi.Name, EntitySetRights.All);
            }

    Funnily enough, even this work around still shows the empty namespace nodes and empty entity containers of the unpublished models eg:


    <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
    <edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
      <edmxBig SmileataServices>
        <Schema Namespace="BBBB" ... />  ***Not wanted***
        <Schema Namespace="CreditorTransactionsDataModel" ... /> ***not wanted***
        <Schema Namespace="SalesOrderDataModel" ...">  ***correctly published***
          <EntityContainer Name="AAAA" /> ***Not wanted***
          <EntityContainer Name="CreditorTransaction_Entities" /> ***Not wanted***
          <EntityContainer Name="SalesOrder_Entities" m:IsDefaultEntityContainer="true"> ***correctly published***
            <EntitySet Name="Contacts" EntityType="SalesOrderDataModel.Contact" />

    ... the rest of the document as expected




    Curiously, given that the method is static and that the config object seems to contain no data about the target type, I cannot see how the data service would avoid this problem except for the reflection type code I have created.


    In fact as a further proof of this. I created a single table edmx with no possibility of conflicting namespaces and no common object names etc and this now shows in the metadata now as well when I use the '*' filter.

    So this is definitely a bug or unexpected behaviour.



    Cheers

    Simon

    Friday, October 17, 2008 12:42 AM

All replies

  • The only reason the types from the other model might be showing up is if they are referenced by types in SalesOrder_Entities.

     

    Can you share the $metadata output or can you send me via email? Looking at the $metadata output, you can easily figure out where the types from the other model (CreditorTransactionDataModel) are getting referenced.

     

    Thanks

    Pratik

    Thursday, October 16, 2008 4:22 PM
    Moderator
  • Hi Pratik,

    $metadata sent to you by email. You see all the types defined and each correctly keep to their own namespace. However both the EntityContainers end up in the namespace of the DataService which is unexpected.




    As a work around I have add this code to the DataService


    public static void InitializeService(IDataServiceConfiguration config)
            {
               
                System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(false);
                System.Diagnostics.StackFrame sf = st.GetFrame(0);
                Type dataServiceObjectContextType = sf.GetMethod().DeclaringType.BaseType.GetGenericArguments()[0];
               
               
                foreach (PropertyInfo pi in dataServiceObjectContextType
                        .GetProperties().Where(p => p.PropertyType.BaseType == typeof(System.Data.Objects.ObjectQuery)))
                    config.SetEntitySetAccessRule(pi.Name, EntitySetRights.All);
            }

    Funnily enough, even this work around still shows the empty namespace nodes and empty entity containers of the unpublished models eg:


    <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
    <edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
      <edmxBig SmileataServices>
        <Schema Namespace="BBBB" ... />  ***Not wanted***
        <Schema Namespace="CreditorTransactionsDataModel" ... /> ***not wanted***
        <Schema Namespace="SalesOrderDataModel" ...">  ***correctly published***
          <EntityContainer Name="AAAA" /> ***Not wanted***
          <EntityContainer Name="CreditorTransaction_Entities" /> ***Not wanted***
          <EntityContainer Name="SalesOrder_Entities" m:IsDefaultEntityContainer="true"> ***correctly published***
            <EntitySet Name="Contacts" EntityType="SalesOrderDataModel.Contact" />

    ... the rest of the document as expected




    Curiously, given that the method is static and that the config object seems to contain no data about the target type, I cannot see how the data service would avoid this problem except for the reflection type code I have created.


    In fact as a further proof of this. I created a single table edmx with no possibility of conflicting namespaces and no common object names etc and this now shows in the metadata now as well when I use the '*' filter.

    So this is definitely a bug or unexpected behaviour.



    Cheers

    Simon

    Friday, October 17, 2008 12:42 AM
  • Thanks for your reply Pratik


    In the 2 connection strings mentioned below, you have specified metadata=res://*, which means load all the resources. If you specify the exact resource file, then it will load metadata only from that specific resource. For more information, look at this link: http://msdn.microsoft.com/en-us/library/cc716756.aspx. It might help you improve the performance also, since you are not loading unnecessary metadata. Specifying the exact metadata to load helps...

    I had simply used the edmx generator to create the models and the connection strings so this was by no means obvious.

    Perhaps improvement in this area could go into a future version of the designer. I still feel that the metadata published should be more selective to the objects being published.

    Imagine if you have private unpublished objects within a model, the metadata would still be available even if you only selective publish part of the model.

    Thanks for your help.

    Cheers
    Simon
    Friday, October 17, 2008 4:29 AM