Tutorial :Subsonic 3 Linq Projection Issue



Question:

OK I'm banging my head against a wall with this one ;-)

Given tables in my database called Address, Customer and CustomerType, I want to display combined summary information about the customer so I create a query to join these two tables and retrieve a specified result.

 var customers = (from c in tblCustomer.All()                          join address in tblAddress.All() on c.Address equals address.AddressId                          join type in tblCustomerType.All() on c.CustomerType equals type.CustomerTypeId                          select new CustomerSummaryView                                     {                                         CustomerName = c.CustomerName,                                         CustomerType = type.Description,                                         Postcode = address.Postcode                                     });      return View(customers);  

CustomerSummaryView is a simple POCO

public class CustomerSummaryView  {      public string Postcode { get; set; }      public string CustomerType { get; set; }      public string CustomerName { get; set; }  }  

Now for some reason, this doesn't work, I get an IEnumerable list of CustomerSummaryView results, each record has a customer name and a postcode but the customer type field is always null.

I've recreated this problem several times with different database tables, and projected classes.

Anyone any ideas?


Solution:1

I can't repro this issue - here's a test I just tried:

[Fact]  public void Joined_Projection_Should_Return_All_Values() {      var qry = (from c in _db.Customers                       join order in _db.Orders on c.CustomerID equals order.CustomerID                       join details in _db.OrderDetails on order.OrderID equals details.OrderID                       join products in _db.Products on details.ProductID equals products.ProductID                       select new CustomerSummaryView                       {                           CustomerID = c.CustomerID,                           OrderID = order.OrderID,                           ProductName = products.ProductName                       });        Assert.True(qry.Count() > 0);        foreach (var view in qry) {          Assert.False(String.IsNullOrEmpty(view.ProductName));          Assert.True(view.OrderID > 0);          Assert.False(String.IsNullOrEmpty(view.CustomerID));      }    }  

This passed perfectly. I'm wondering if you're using a reserved word in there?


Solution:2

This post seems to be referring to a similar issue...

http://groups.google.com/group/subsonicproject/browse_thread/thread/2b569539b7f67a34?hl=en&pli=1


Solution:3

Yes, the reason Rob's example works is because his projection's property names match exactly, whereas John's original example has a difference between CustomerType and type.Description.

This shouldn't have been a problem, but it was - the Projection Mapper was looking for properties of the same name and wasn't mapping a value if it didn't find a match. Therefore, your projection objects' properties would be default values for its type if there wasn't an exact name match.

The good news is, I got the latest source today and built a new Subsonic.Core.dll and the behavior is now fixed.

So John's code above should work as expected.


Solution:4

I just downloaded the latest build from 3/21/2010, which is about 2 months after the last poster on this thread, and the problem still exists in the packaged binary. Bummer.

Here what I have to do:

        var data =              (from m in Metric.All()               where m.ParentMetricId == parentId               select new                      {                           m.MetricName,                           m.MetricId,                      })                      .ToList();            var treeData =              from d in data              select new TreeViewItem                      {                          Text = d.MetricName,                          Value = d.MetricId.ToString(),                          LoadOnDemand = true,                          Enabled = true,                      };            return new JsonResult { Data = treeData };  

If I try to do the projection directly from the Subsonic query, the Text property ends up with the ID, and the Value property ends up with the Name. Very strange.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »