Hello, I'm needing help with a query I've been working on for a week now, I've tried using IEnumerable and tried using the query like a var, to no avail. Basically I'm just trying to query a range using LINQ for example, I need to find the range of invoices between $250 - $550 in descQuantity. My query is close to the bottom called rangeQuery. Thank you. Also, a strange exception keeps telling me to look at lines 104 and 107...I don't have a line 107 and 104 is a bracket at the end(2nd to last)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class LINQWithArrayOfObjects
{

public static void Main(string[] args)
{
    // initialize array of invoices
    Invoice[] theInvoice = {
        new Invoice( 83, "Electric sander", 7,57.98M ),
        new Invoice( 24, "Power saw", 18, 99.99M ),
        new Invoice( 7, "Sledge hammer", 11, 21.50M),
        new Invoice( 77, "Hammer", 76, 11.99M),
        new Invoice( 39, "Lawn mower", 3, 79.50M),
        new Invoice( 68, "Screwdriver", 106, 6.99M ),
        new Invoice( 56, "Jig saw", 21, 11.00M),
        new Invoice( 3, "Wrench", 34, 7.50M ) 
          };

    //Sorted by part Description
    var sortedByDesc =
        from inv in theInvoice
        orderby inv.PartDescription
        select inv;

    Console.WriteLine("by part Description");

    Console.WriteLine("==========================================");
    // dispay by part Description
    foreach (var inv in sortedByDesc)
    {
        Console.WriteLine(inv.ToString());
    }
    Console.WriteLine("==========================================");

    // Sorted by price
    var sortedByPrice =
        from priceInvoice in theInvoice
        orderby priceInvoice.Price
        select priceInvoice;

    // display by price
    Console.WriteLine("by part Price");

    Console.WriteLine("==========================================");
    foreach (var priceInvoice in sortedByPrice)
    {
        Console.WriteLine(priceInvoice.ToString());
    }
    Console.WriteLine("==========================================");

    // sort by quantity
    var partQuantity =
        from inv in theInvoice
        orderby inv.Quantity
        select new { inv.PartDescription, inv.Quantity };

    //display by quantity
    Console.WriteLine("by part Quantity");

    Console.WriteLine("==========================================");
    foreach (var inv in partQuantity)
    {
        Console.WriteLine(inv.ToString());
    }

    Console.WriteLine("==========================================");

    // Invoice Total
    var descQuantity =
        from inv in theInvoice
        let InvoiceTotal = inv.Price * inv.Quantity
        orderby InvoiceTotal
        select new { InvoiceTotal, inv.PartDescription };
    Console.WriteLine("Invoice Total");

    Console.WriteLine("==========================================");
    // display Invoice Totals
    foreach (var inv in descQuantity)

        Console.WriteLine(inv.ToString());
    Console.WriteLine("==========================================");

    Console.WriteLine("Range of $200 - $500");

    Console.WriteLine("==========================================");




       var rangeQuery =
           from InvoiceTotal in descQuantity
           where Convert.ToDecimal(InvoiceTotal) >= 200 && Convert.ToDecimal (InvoiceTotal) <= 500
           select InvoiceTotal;

    foreach (var InvoiceTotal in rangeQuery)
    {
        Console.WriteLine(InvoiceTotal);

    }
}

Here is a corrected example:

  IEnumerable<int> enmRange = Enumerable.Range(200, 350);
  (//var inRange200to550 =
     from inv in theInvoice
     let invTotal = ((double)inv.Price * inv.Quantity)
     where enmRange.Contains((int)invTotal)
     orderby invTotal
     select new { InvoiceTotal = invTotal, inv.PartDescription }
  ).ToList().ForEach(inv => Console.WriteLine("${0}\t{1}", inv.InvoiceTotal, inv.PartDescription));

Edited 4 Years Ago by thines01: formatting

Try using liqn with lambd
a expressions:

var query = descQuantity.Where(w=>w.Price => 250 && w.Price <= 550).Select(s => new Invoice { Id = s.Id, Name = s.Name, Quantity = s.Quantity }).ToList();

I dont know you actaul properties of the Invoice class, so rename them (inside brackets).

@Mitja_Bonca: Did you see how I did the comparision to the range?
Also, you have a typo in your code right before the 250.

Also, the problem comes in where the total is used with the returned object, so the combination would create an anonymous type, but the total has to be pulled out of it instead of the whole type.

@kiail could use >> InvoiceTotal.InvoiceTotal << to solve the problem with the current code as it looks like the problem is just the similar name that is keeping this from being what is expected.

If you attempt to compile this, the properties of the class reveal themselves.

I made a full mock-up of it, if you want to see it.

Edited 4 Years Ago by thines01: formatting

Thx for reminding me (it really was a type). Here is repaired code:

var query = descQuantity.Where(w=>w.Price >= 250M && w.Price <= 550M).Select(s => new Invoice { Id = s.Id, Name = s.Name, Quantity = s.Quantity }).ToList();

Here is my usual "overkill" example that hopefully makes the right point.

using System;
using System.Collections.Generic;
using System.Linq;

public class LINQWithArrayOfObjects
{
   public class Invoice
   {
      public string PartDescription { get; set; }
      public double Price { get; set; }
      public int Quantity { get; set; }

      public Invoice(int Quantity, string PartDescription, double Price)
      {
         this.Quantity = Quantity;
         this.PartDescription = PartDescription;
         this.Price = Price;
      }

      public override string ToString()
      {
         return Quantity.ToString() + '\t' +
            PartDescription.PadRight(20, ' ') + '\t' +
            "$"+Price.ToString("F2");
      }

      public override bool Equals(object obj)
      {
         return this.ToString().Equals(((Invoice)obj).ToString());
      }

      public override int GetHashCode()
      {
         return this.ToString().GetHashCode();
      }
   }

   private static void BoxPrint(string str)
   {
      Console.WriteLine( Environment.NewLine +
         "=========================================="
         + Environment.NewLine + str + Environment.NewLine +
         "==========================================");
   }

   public static void Main(string[] args)
   {
      Invoice[] theInvoice = {
         new Invoice( 8, "Electric sander", 75.98),
         new Invoice( 2, "Power saw", 89.99),
         new Invoice( 7, "Sledge hammer", 21.50),
         new Invoice( 14, "Hammer", 11.99),
         new Invoice( 9, "Lawn mower", 379.50),
         new Invoice( 16, "Screwdriver", 6.99),
         new Invoice( 8, "Jig saw", 31.00),
         new Invoice( 3, "Wrench", 7.50)
      };

      BoxPrint("Sorted by part Description");
      (//List<Invoice> sortedByDesc =
         from inv in theInvoice
         orderby inv.PartDescription
         select inv
      ).ToList().ForEach(inv => Console.WriteLine(inv.ToString()));

      BoxPrint("Sorted by Price");
      (//List<Invoice> sortedByPrice =
         from inv in theInvoice
         orderby inv.Price
         select inv
      ).ToList().ForEach(inv => Console.WriteLine(inv.ToString()));

      BoxPrint("Sorted by Quantity");
      (//List<Invoice> sortedByQuantity =
         from inv in theInvoice
         orderby inv.Quantity
         select inv
      ).ToList().ForEach(inv => Console.WriteLine(inv.ToString()));

      IEnumerable<int> enmRange = Enumerable.Range(200, 350);
      BoxPrint("Invoice Total: Range of $200 - $550");
      (//var inRange200to550 =
         from inv in theInvoice
         let invTotal = ((double)inv.Price * inv.Quantity)
         where enmRange.Contains((int)invTotal)
         orderby invTotal
         select new { InvoiceTotal = invTotal, inv.PartDescription }
      ).ToList().ForEach(inv => Console.WriteLine("${0}\t{1}", inv.InvoiceTotal, inv.PartDescription));
   }
}

One last mod (more overkill) showing a different technique to get the total:

using System;
using System.Collections.Generic;
using System.Linq;

namespace DW_419286_CS_CON
{
   public partial class LINQWithArrayOfObjects
   {
      private static IEnumerable<int> _enmRange = Enumerable.Range(200, 350);//200-550
      private static Func<Invoice, int> _total = i => (int)((double)i.Price * i.Quantity);

      public static void Main(string[] args)
      {
         BoxPrint("Sorted by part Description");
         theInvoice.OrderBy(i => i.PartDescription).ToList().ForEach(i => Console.WriteLine(i.ToString()));

         BoxPrint("Sorted by Price");
         theInvoice.OrderBy(i => i.Price).ToList().ForEach(i => Console.WriteLine(i.ToString()));

         BoxPrint("Sorted by Quantity");
         theInvoice.OrderBy(i => i.Quantity).ToList().ForEach(i => Console.WriteLine(i.ToString()));

         BoxPrint("Invoice Total: Range of $200 - $550");
         theInvoice
            .Select(i => new {t=_total(i), inv=i})
            .Where(i => _enmRange.Contains(i.t))
            .OrderBy(i => i.t).ToList()
            .ForEach(i => Console.WriteLine("${0}\t{1}", i.t, i.inv.PartDescription));
      }
   }
}

okay, i might be ridiculed for this next one, but why is the range for 200-550, 200-350 in the EnumerableRange(I'm still green)? how does that work? Say for example, if I wanted to change the range real quick to 50 - 800, how would I know which numbers to put in?

If you look at the parameter list, the first param is the starting value and the second is the number of elements.
So for 50-800, you would need (50, 751).

So, my example is actually 1-off, but you get the idea.

In order to have 50-100, you would actually need to have 51 elements.

int iStart = 50;
int iEnd = 100;
Enumerable.Range(iStart, (iEnd+1)-iStart).ToList().ForEach(i => Console.WriteLine(i));

Edited 4 Years Ago by thines01: clarity

oh wow, that makes total sense, I don't know why I didn't see that. Thanks a million.

This question has already been answered. Start a new discussion instead.