locked
LightSwitch + WCFRIA :- How to eagerly load the child relationship data along with the parent RRS feed

  • Question

  • Hi All,

    I need to implement a one : many relationship in a WCFRIA service and use that as a data source in my LightSwitch app. For example, say Category and Products (category has many products).

    I am able to define the relation in my service using the AssociationAttribute and LightSwitch imports it correctly as well. The problem occurs when loading the data. 

    I have product entities available when I create the category instance and I am adding them to the appropriate Product collection within the category at that time. But these products do not show up on my screen. When I stepped through the code I found that the default query method for Products is being called ( instead of using the products I supplied ). I do not have access to the Product entities when the default query for Products is called, I only have access to them when I create my Category entity. 

    Is there any way I can get this to work? I already tried using [Include] on the child collection, but that made no difference. Also, I cannot work with a flattened entity so that solution won't work either.

    Below is the sample code to show what I have done so far. You will find in the Category_Default() method that I am loading Products right there. The Product_Default method simply returns null.

        public class Category
        {
            [Key]
            public string CategoryId { get; set; }
            public string Name { get; set; }
    
            private ICollection<Product> _products = null;
    
            public Category()
            {
                CategoryId = Guid.NewGuid().ToString();
            }
    
            [Include]
            [Association("FK_C_P", "CategoryId", "CategoryId", IsForeignKey = false)]
            public ICollection<Product> Products
            {
                get { return _products; }
                set { _products = value; }
            }
    
            public void AddProduct(Product p)
            {
                if (p == null)
                {
                    return;
                }
    
                if (_products == null)
                {
                    _products = new List<Product>();
                }
    
                p.CategoryId = this.CategoryId;
                p.Cat = this;
                _products.Add(p);
            }
        }
    
        public class Product
        {
            [Key]
            public string ProductId { get; set; }
            public string ProductName { get; set; }
            public string CategoryId { get; set; }
    
            public Product()
            {
                ProductId = Guid.NewGuid().ToString();
            }
    
            [Include]
            [Association("FK_C_P", "CategoryId", "CategoryId", IsForeignKey = true)]
            public Category Cat { get; set; }
    
        }
    
    
            [Query(IsDefault = true)]
            public IQueryable<Category> Category_Default()
            {
                var result = new List<Category>();
    
                var c = new Category();
                c.Name = "Category 1";
                c.AddProduct(new Product() { ProductName = "Product 1" });
                c.AddProduct(new Product() { ProductName = "Product 2" });
                c.AddProduct(new Product() { ProductName = "Product 3" });
                c.AddProduct(new Product() { ProductName = "Product 4" });
    
                result.Add(om);
    
                return result.AsQueryable();
            }
    
            [Query(IsDefault = true)]
            public IQueryable<Product> Product_Default()
            {
                return null;
            }

    Both, Category and Product, would be read-only in this case, so would setting some readonly attribute somewhere help? If so, how would I do that?

    Thanks in advance!

    Jayesh






    • Edited by JayeshK Tuesday, August 13, 2013 7:12 PM
    Tuesday, August 13, 2013 6:59 PM

Answers

  • Turns out that WCFRIA + LS is limiting in this regard. So there was no way to avoid the calling of the default query of the child collection and no way to eagerly load the child. 

    So I worked around this by persisting the child collection to the filesystem and saving the filename in the parent object. To get the child collection I then had to pass the filename to a query method and then retrieve the persisted collection from the filesystem. 

    Once I did this I had no need to keep the relationship in WCFRIA so I just removed it.

    If anyone else finds a better way of doing this then please do let me know. Until then I am marking this comment as an answer. 

    Thanks.

    • Marked as answer by JayeshK Wednesday, September 25, 2013 6:28 PM
    Wednesday, September 25, 2013 6:28 PM