36
var cityList = from country in 
                    doc.Element("result")
                    .Element("cities")
                    .Descendants("city")
select new {
        Name = country.Element("name").Value,
        Code = country.Element("code").Value,
        CountryCode = int.Parse(country
                      .Element("countrycode")
                      .Value)
    };

foreach(var citee in cityList)
{
    City city = new City();
    city.CountryID = from cnt in db.Countries 
                     where cnt.DOTWInternalID == citee.CountryCode 
                     select cnt.ID;
}

I'm getting an error on the second query as seen in the title of this post. I tried converting to int to nullable int but nothing worked. Help me, guys.

Thanks

Lewis86
  • 511
  • 6
  • 15
Aneef
  • 3,641
  • 10
  • 43
  • 67
  • Is there more to your example? It looks like the City object will always get discarded after every iteration of the loop? – Roman Apr 04 '10 at 17:42

6 Answers6

50

it will return an iQueryable, you will need to do something like using the First

cit.CountryID = db.Countries.First(a=>a.DOTWInternalID == citee.CountryCode).ID
Pharabus
  • 6,081
  • 1
  • 26
  • 39
  • oops i was so dumb to ask this question, actually i didn't notice this, actually i was all this time concentrating on this cnt.DOTWInternalID == citee.CountryCode not the returning ID.. *sigh* – Aneef Apr 04 '10 at 17:38
  • 4
    Not dumb, I'm starting with linq and this answer was just what I needed! thanks – pauloya Aug 20 '10 at 20:30
16

It has elapsed a long time since the last update to the post but i think it's worth improving the solution.

In my opinion the solutions posted for this particular scenario are not the best way in terms of performace to get the ID you need. A better solution is as follows.

db.Countries.Where(a=>a.DOTWInternalID == citee.CountryCode)
            .Select(a => a.ID).FirstOrDefault();

The previous statemants basically runs a SQL query similar to the following one:

SELECT TOP (1) ID
FROM [dbo].[Countries]
WHERE DOTWInternalID = 123

The proposed solutions work but basically do a "SELECT *" to create the entity with all the values and then obtain the ID from the object just created.

You can use Linqpad to actually see the generated SQL and tune up LINQ queries or Lambdas.

Hope it helps to some others that get to this post.

Charles
  • 696
  • 1
  • 10
  • 19
  • Your solution worked for me... I'm just wondering why `FirstOrDefault()` works fine, but `FirstOrDefaultAsync()` throws an error: `Cannot implicitly convert type 'System.Threading.Tasks.Task' to 'int'` – half of a glazier Feb 18 '20 at 12:25
  • FirstOrDefault() is a synchronous method and will return int, while FirstOrDefaultAsync() will return a Task which in this case is int. I suggest you to read the areticle below to get a better understanding of asynchronous programming: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/ – Charles Feb 19 '20 at 16:31
6

Here is the problem and solution

from cnt in db.Countries where cnt.DOTWInternalID == citee.CountryCode select cnt.ID part. If you omit the ID then it returns a Generic IEnumerable with Country(hoping that you have Country class). So what you have to do is first return the select criteria and select the first row then the ID field. Same like shown below.

cit.CountryID = (from cnt in db.Countries where cnt.DOTWInternalID == citee.CountryCode   select cnt).First<Country>().ID;

This will solve your problem.

wonde
  • 674
  • 1
  • 8
  • 19
5

IQueryable is not a single int - but a query that can represent a collection.

Maggie
  • 1,546
  • 16
  • 27
2

As the error message says, your Linq query returns an System.Linq.IQueryable (for all intents and purposes a collection of ints). If you'd like to get one of them, you can either call First or ElementAt(n) to get the n'th element.

Roman
  • 19,581
  • 6
  • 68
  • 84
0
cit.CountryID = db.Countries.First(a=>a.DOTWInternalID == citee.CountryCode).ID