tags:

views:

728

answers:

2

I have a linq query that returns a brief order summary - product description and product price that gets bound to a data control. I want to add a row to be bound in this same control that displays tax information. The product description column would simply say "Tax" and the product price column would give a tax amount.

I used to retrieve a DataTable of these results and simply do a NewRow() and then set the datasource of my control as the DataTable. I'm looking for the equivalent technique when using LINQ to SQL. Thanks.

+1  A: 

In order to make it easy to add another "row" to the results of the LINQ query, you might want to consider creating a class to hold the results of the query. Then you could convert the results to a List, calculate the tax, and append the tax as an object of the class.

public class OrderSummary
{
    public string Description { get; set; }
    public decimal Amount { get; set; }
}


var taxRate = ...
var orderSummary = db.Orders.Where( o => o.ID == id )
                            .Select( o => new OrderSummary
                                {
                                    Description = o.Product
                                                   .Details
                                                   .Description,
                                    Amount = o.Qty * o.Product.Price
                                })
                            .ToList();

var tax = new OrderSummary
              {
                  Description = "Tax",
                  Amount = orderSummary.Sum( o => o.Amount * taxRate );
              };
orderSummary.Add( tax );

Then you can bind the list to your control using Description as the key and Amount as the value.

tvanfosson
This seems like it's going to work. One question, I'm grabbing results from an order detail table which is related to the product table, so in order to get to the Description, I have to do orderSummary.Product.Description = "Tax". Am I able to do that? It's not working when I add it like that.
Are you selecting into a new class as I described? I'll update my example to reflect the indirection.
tvanfosson
Currently I have a function that returns an order detail object, but I could change the class if it's easier.
Since what you are presenting is not really an order detail, I would use the "view" class approach and create a new class.
tvanfosson
+2  A: 

orderSummary.Union(taxRow)

John Saunders
I'm trying this one and getting The type arguments for method 'System.Linq.Enumerable.Union<TSource>(System.Collections.Generic.IEnumerable<TSource>, System.Collections.Generic.IEnumerable<TSource>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
You might need to do something like orderSummaries.Union(new List<OrderSummary>(){new OrderSummary(){ProductDescription="Tax",Amount=taxAmount}}); //Same point, make the tax row a 1-item list of OrderSummary, union it to the rest.
John Saunders
+1 - btw, use: orderSummaries.Union(new[] {new OrderSummary(){...}); for a shorter version:)
eglasius