tags:

views:

169

answers:

3

Hi there, I have a Linq to SQl query in C#

var queryGetAllPricingData = from i in dB.Invoices
                         join c in dB.Contracts
                         on i.ContractId 
                         equals 
                         c.ContractId
                         where i.InvoiceStatusId == 100
                         select new { i, c]};

Then I do a test for any results:

if (queryGetAllPricingData.Count() > 0)

Then I want to use the results in a new method.

What do I pass to the new method? This does not appear to work

if (queryGetAllPricingData.Count() > 0)
{
     GetPricingModel(queryGetAllPricingData);
}

internal void GetPricingModel(IQueryable queryGetAllPricingData)
{
foreach (var record in queryGetAllPricingData)
  {
     DO SOMETHING;
  }
}

What should I be doing?

+3  A: 

Please see this question for answers: http://stackoverflow.com/questions/55101/using-linq-how-can-i-pass-a-var-back-from-a-method

Michael Edwards
A: 

You cannot pass anonymous types into a new method, what you need to do is create a class to hold the information

Stan R.
+1  A: 

Well, your problem is this:

var queryGetAllPricingData = from i in dB.Invoices
                           .....
                         select new { i, c]};

You're getting back an IQueryable of an anonymous type, and you can't pass those around.

You'll need to create a container type for this, something like:

public class InvoiceContract
{
   Invoice inv { get; set; }
   Contract contr { get; set; } 
}

and then change your LINQ query to:

var queryGetAllPricingData = from i in dB.Invoices
                           .....
                         select new InvoiceContract { inv => i, contr => c };

and then use IQueryable<InvoiceContainer> as your type on the second method you want to call:

internal void GetPricingModel(IQueryable<InvoiceContract> queryGetAllPricingData)

That should work (I hope! No way of testing this right now, all off the top of my head)

Marc

marc_s
I don't understand how you get the types Invoice and Contract in the data container class?
Richard210363
OK I do now. LINQ created the tables as classes.Shouldn't the class implement IEnumerable<> and if so which Type do I use?
Richard210363
@Richard: LINQ does create IEnumerable<Invoice> and IEnumerable<Contract> in your "code-behind" file for the DBML model. However, it only creates those IEnumerable<T> for single types, e.g. for Invoice or for Contract separately - how should it know whether you want to combine Contract and Invoice, or Invoice and Customer into extra "container" classes.... it can't know that (or it would have to create every possible combination of two entity classes - but then what about containers with any 3 of the entity classes)......
marc_s
OK, however, when I do what you have described I get an error at the bracket after "select new InvoiceContract { ".Cannot initialize type 'InvoiceContract' with a collection initializer because it does not implement 'System.Collections.IEnumerable'So what do I have to do to the container class?
Richard210363
I'm wondering if I am approaching this all wrong.I want to take a large set of data and depending on a couple of flags in the data I do a 1 of 4 calculations and save the data back.In ADO I would have made a dataset, passed it around to the calculation methods and then updated the dB.Am I using LINQ in the wrong way?
Richard210363
Well, the IEnumerable<T> is a bit different from Datasets - and I do see the trouble now with your error message - I'll have to see what I can do about that...
marc_s