none
strange problem serializing an entitiy RRS feed

  • Question

  • Hi, i have tables in database which i drageed to the o/r designer to generate appropriate classes.

    i changed the property of the page to allow serialization.

    i then use linq to get the tables according to a specific id received by the client, and i get a list of items.

    each item in the list has internal lists of objects which represents other tables in relationship with it by foreign key primary key relationship.

    I'm using wcf rest as my web service, when client receive the entity, it has none of the internal lists indise it.

    The strange thing is if i debug and watch the internal list inside the entity object before it is sent to the user, the list that i watched is sent fine.

    how could it be possible that watching the object in the debugger affects the result of the code???


    Tuesday, July 26, 2011 7:19 AM

Answers

  • Hi ronenfe.

    I'm trying to understand your problem.

    What do you do exactly with the result entities?

    I mean, do you only query the context to get them and then return them?

    If you do that, don't forget that Entity Framework has Lazy Loading by default, this means that the relationships of an Entity won't be pulled from DB until they are needed, enumerating them or just referencing one of their properties, or even using the Include method of ObjectQuery<T>.

    The thing about debugging is that, when you look at the property of an entity that has a list of other entities, you are enumerating that list and that is why you are seeing the related entities when debugging.

    Supose that we have UserEntity and TeamEntity, and a ManyToMany association relating them.

    If I just do:  

     

    var query = 
     from u in context.UserEntitySet
     select u;
    
    return query.ToList();
    I will only get the Users without their Teams.

     

    So, in order to get them all I will change the code to look something like this: 

    var query =
     from u in context.UserEntitySet.Include("Teams")
     select u;
    
    return query.ToList();
    Please, correct me if this is not your problem.

     

    Regards,

    Wednesday, July 27, 2011 4:29 AM
  • Thanks, you understood exactly my problem, that explains why when i'm doing watch it retrieves all internal lists. however it seems i was a little wrong, i am not using entity framework, i'm using linq to sql.

    The "include()" doesn't exist when i'm using DataContext class.

    but you pointed me to the right direction, i searched lazy  in the context of linq to sql and found this:

    http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/10/06/linq-to-sql-deferred-loading-lazy-load.aspx

    BlogDataContext ctx = new BlogDataContext(...);

    ctx.DeferredLoadingEnabled = false;

     

    DataLoadOptions dlo = new DataLoadOptions();

    dlo.LoadWith<Blog>(b => b.Posts);

    ctx.LoadOptions = dlo;

     

    var query = from b in ctx.Blogs

                select b;

     

    foreach (Blog b in query)

    {

        Console.WriteLine("{0} has {1} posts", b.BlogName, b.Posts.Count);

    }

    which solves my problem, i still need to figure out how to include multiple internal objects in the loadwith lambda expression.

    here: i found a better article with the solution to include multiple objects:

    http://eprystupa.wordpress.com/2009/11/26/linq-to-sql-tricks-building-efficient-queries-that-include-reference-data-or-child-entities/

    private static IEnumerable<CustomerAddress> BuildQuery(
      AdventureWorksDataContext ctx)
    {
      // NEW CODE - LoadWith options
      var dataOptions = new System.Data.Linq.DataLoadOptions();
      dataOptions.LoadWith<CustomerAddress>(ca => ca.Address);
      dataOptions.LoadWith<CustomerAddress>(ca => ca.Customer);
      ctx.LoadOptions = dataOptions;
      // END NEW CODE - LoadWith options
    
      var q = (from ca in ctx.CustomerAddresses
           select ca).Take(3);
      return q;
    }

     





    • Marked as answer by ronenfe Wednesday, July 27, 2011 2:47 PM
    Wednesday, July 27, 2011 2:41 PM

All replies

  • Hi ronenfe.

    I'm trying to understand your problem.

    What do you do exactly with the result entities?

    I mean, do you only query the context to get them and then return them?

    If you do that, don't forget that Entity Framework has Lazy Loading by default, this means that the relationships of an Entity won't be pulled from DB until they are needed, enumerating them or just referencing one of their properties, or even using the Include method of ObjectQuery<T>.

    The thing about debugging is that, when you look at the property of an entity that has a list of other entities, you are enumerating that list and that is why you are seeing the related entities when debugging.

    Supose that we have UserEntity and TeamEntity, and a ManyToMany association relating them.

    If I just do:  

     

    var query = 
     from u in context.UserEntitySet
     select u;
    
    return query.ToList();
    I will only get the Users without their Teams.

     

    So, in order to get them all I will change the code to look something like this: 

    var query =
     from u in context.UserEntitySet.Include("Teams")
     select u;
    
    return query.ToList();
    Please, correct me if this is not your problem.

     

    Regards,

    Wednesday, July 27, 2011 4:29 AM
  • Thanks, you understood exactly my problem, that explains why when i'm doing watch it retrieves all internal lists. however it seems i was a little wrong, i am not using entity framework, i'm using linq to sql.

    The "include()" doesn't exist when i'm using DataContext class.

    but you pointed me to the right direction, i searched lazy  in the context of linq to sql and found this:

    http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/10/06/linq-to-sql-deferred-loading-lazy-load.aspx

    BlogDataContext ctx = new BlogDataContext(...);

    ctx.DeferredLoadingEnabled = false;

     

    DataLoadOptions dlo = new DataLoadOptions();

    dlo.LoadWith<Blog>(b => b.Posts);

    ctx.LoadOptions = dlo;

     

    var query = from b in ctx.Blogs

                select b;

     

    foreach (Blog b in query)

    {

        Console.WriteLine("{0} has {1} posts", b.BlogName, b.Posts.Count);

    }

    which solves my problem, i still need to figure out how to include multiple internal objects in the loadwith lambda expression.

    here: i found a better article with the solution to include multiple objects:

    http://eprystupa.wordpress.com/2009/11/26/linq-to-sql-tricks-building-efficient-queries-that-include-reference-data-or-child-entities/

    private static IEnumerable<CustomerAddress> BuildQuery(
      AdventureWorksDataContext ctx)
    {
      // NEW CODE - LoadWith options
      var dataOptions = new System.Data.Linq.DataLoadOptions();
      dataOptions.LoadWith<CustomerAddress>(ca => ca.Address);
      dataOptions.LoadWith<CustomerAddress>(ca => ca.Customer);
      ctx.LoadOptions = dataOptions;
      // END NEW CODE - LoadWith options
    
      var q = (from ca in ctx.CustomerAddresses
           select ca).Take(3);
      return q;
    }

     





    • Marked as answer by ronenfe Wednesday, July 27, 2011 2:47 PM
    Wednesday, July 27, 2011 2:41 PM