locked
is not a valid property. Properties whose types are collection of primitives or complex types are not supported RRS feed

  • Question

  • I have some simple code that looks something like this; 

      [DataServiceKey("Id")]
      public class Database {
    
        public int Id { get; set; }
    
        public string Name { get; set; }
    
        public int Size { get; set; }
    
        //private Table _Tabel;
    
        //public Table Tabel {
        //  get { return _Tabel; }
        //  set { _Tabel = value; }
        //}
    
        public List<Table> Tables { get; set; }
    
        public Database(int id, string name, int size) {
          Id = id;
          Name = name;
          Size = size;
          Tables = new List<Table>();
    
        }
      }

     If I swap out Tabel for Tables as a property then all is well, in its current form I get the error in the title. This is VS2010 RTM. Definition of Table is below

      public class Table {
        public int Id { get; set; }
        public string Name { get; set; }
    
        public Table() {
          Id = 1;
          Name = "Foo";
        }
    
        //public Table(int id, string name) {
        //  _Id = id;
        //  _Name = name;
        //}
      }
    Friday, June 4, 2010 4:55 AM

Answers

  • Hi,

    Yes - that's what I'm saying. I understand that for some data it is not ideal, but that's the current feature set we support. The feature you're asking for (entities which are not exposed at the top-level, basically hierarchical data models) is called containment. We are aware of it, and we are definitely considering it for our next release. If you want, you can vote for it on our connect site here: https://connect.microsoft.com/dataplatform/content/content.aspx?ContentID=15540&wa=wsignin1.0

    Currently the design is such, that each entity must be addresable on the root, that is there must be a URL in form service/entityset(keyvalues) for every single entity in the model. That means that each entity must belong to an entity set which is exposed at the root level.

    Thanks,


    Vitek Karas [MSFT]
    Monday, June 7, 2010 12:34 PM
    Moderator

All replies

  • Hi,

    The problem is that your Table class is not recognized as an entity type. We use just a simple algorithm to determine if a given class is an entity:

    - If it has a property called ID (mind the casing), then it's an entity and the ID is the key property

    - If it has a property called ClassNameID (again mind the casing), then it's an entity and the ID is the key property

    - If it has the DataServiceKey attribute, then it's an entity and all the properties listed in that attribute are key properties.

    So in your case, if you want to make Table an entity, just add the DataServiceKey("Id") attribute on it.

    Thanks,


    Vitek Karas [MSFT]
    Friday, June 4, 2010 8:31 AM
    Moderator
  • Thx for the response, very educational. However I made a copy and paste error and did not include the DataServiceKey attribute line on the Table entity, it already has it. I also tried changing Id to be ID and that did not work either.
    Friday, June 4, 2010 4:59 PM
  • Hi,

    There's one more condition for a class to be recognized as entity and that is, that you must have a property on your context class of type IQueryable<T> where T is the class in question. So in your case, your context class (the one you pass as T to the DataService<T>) should have two properties, one of type IQueryable<Table> and the other IQueryable<Database>. If that's not the case then you would get the error you are getting (or similar).

    Thanks,


    Vitek Karas [MSFT]
    Sunday, June 6, 2010 8:31 AM
    Moderator
  • Ok that helps but I am a little confused, I choose this repro as it represents a similar model tot he real one I am trying to map. In my repro a database has a collection of tables (would also have views, stored procedures a bunch of stuff) and each table has a collection of columns.

    If my databaseservice class looks like this 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace Repro {
      public class DatabaseService {
        List<Database> database = new List<Database>(){
    		      new Database(1, "Northwind", 20),
    		      new Database(2, "Pubs", 5),
    		      new Database(3, "AdventureWorks", 200),
    		      new Database(4, "AdventureWorks2008", 500)
    		    };
    
        public IQueryable<Database> Database {
          get {
            return database.AsQueryable<Database>();
          }
        }
      }
    }

     Are you saying the database service needs to explictly expose all of the collections/classes below it? That seems like the wrong scope...

    Monday, June 7, 2010 5:29 AM
  • Hi,

    Yes - that's what I'm saying. I understand that for some data it is not ideal, but that's the current feature set we support. The feature you're asking for (entities which are not exposed at the top-level, basically hierarchical data models) is called containment. We are aware of it, and we are definitely considering it for our next release. If you want, you can vote for it on our connect site here: https://connect.microsoft.com/dataplatform/content/content.aspx?ContentID=15540&wa=wsignin1.0

    Currently the design is such, that each entity must be addresable on the root, that is there must be a URL in form service/entityset(keyvalues) for every single entity in the model. That means that each entity must belong to an entity set which is exposed at the root level.

    Thanks,


    Vitek Karas [MSFT]
    Monday, June 7, 2010 12:34 PM
    Moderator