22

I want to retrieve data from the database in different tables by relation, but I get an error that I don't know how to handle.

int customer_id = int.Parse(this.comboBoxnamecustomer.SelectedValue.ToString());

a = (from c in db.Invoices where c.CustomerID == customer_id select new { 
        customerName = c.Customer.Name,
        ProductName = c.InvoiceItems
            .Where(x => x.InvoiceId == c.InvoiceId)
            .First().Product.ProductsName.Name
    }).ToList();

Unhandled Exception: System.NotSupportedException: The method 'First' can only be used as a final query operation. Consider using the method 'FirstOrDefault' in this instance instead.

The problem is with the .First() method, but if I remove it I can't pass to another table.

Alex Angas
  • 59,219
  • 41
  • 137
  • 210
Dana Ali
  • 261
  • 1
  • 2
  • 5
  • 1
    http://stackoverflow.com/questions/7811544/why-does-ef-throw-notsupportedexception-the-method-first-can-only-be-used-as?rq=1 – Eugene Aug 14 '13 at 12:49
  • I'm not sure what your database structure is, but it seems like there is something else logically wrong with your query. Wouldn't c.InvoiceItems already only be those where the InvoiceItem.InvoiceId = Invoice.InvoiceId? If you've defined that relationship already, your use of Where seems redundant. Also do you really want the Product name of just the first item in each invoice the customer has? – hatchet - done with SOverflow Aug 14 '13 at 13:18

2 Answers2

32

Your solution, as the error states - is to use FirstOrDefault. This, however, will return null if the result of ProductName query is empty, meaning you'd get a NullReferenceException from FirstOrDefault().Product.ProductsName.Name. This is solved by moving the property transform earlier in the query, before the call to FirstOrDefault():

a = (from c in db.Invoices where c.CustomerID == customer_id select new { 
     customerName=c.Customer.Name,
     ProductName=c.InvoiceItems.Where(x=> x.InvoiceId==c.InvoiceId)
                               .Select(i => i.Product.ProductsName.Name)
                               .FirstOrDefault()
}).ToList();
RoadieRich
  • 6,330
  • 3
  • 35
  • 52
1

The error is stating that you should use FirstOrDefault() instead of First()

Not sure what the question is

int customer_id = int.Parse(this.comboBoxnamecustomer.SelectedValue.ToString());

a = (from c in db.Invoices where c.CustomerID == customer_id select new { 
         customerName=c.Customer.Name,ProductName=c.InvoiceItems.Where(x=> x.InvoiceId==c.InvoiceId).FirstOrDefault().Product.ProductsName.Name
        }).ToList();
        dataGridViekryar.DataSource = a;

Of course this will throw an error if there isn't any items from your query (NullReferenceException)

Sayse
  • 42,633
  • 14
  • 77
  • 146
  • The *consideration*, is invalid at best. The block `FirstOrDefault().Product` is a recipe for a `NullReferenceException`. I would say the exception thrown by `First()` is much more accurate. – Mike Perrenoud Aug 14 '13 at 12:46
  • 1
    @TheSolution I agree with you which is why I'm unsure where the suggestion came from – Sayse Aug 14 '13 at 12:50
  • 1
    But the problem is different I guess it could be the language construct for Linq query expression that you can't use first() when creating a where clause. "Where" requires a value to compare not a possible exception. – vendettamit Aug 14 '13 at 12:52