Subsonic 3 Linq Projection Issue

2019-02-28 16:52发布

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?

4条回答
The star\"
2楼-- · 2019-02-28 17:11

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.

查看更多
家丑人穷心不美
3楼-- · 2019-02-28 17:21

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.

查看更多
何必那么认真
4楼-- · 2019-02-28 17:23

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?

查看更多
登录 后发表回答