Основной вопрос LinqToSql: почему не скомпилируется? - PullRequest
4 голосов
/ 15 апреля 2009

В последнее время я знакомился с LinqToSQL через плохо сделанный проект на работе. Мне интересно, почему это работает:

var territories = db.Territories.Where(t => t.PendingUserCount > 0);

Но это приводит к ошибке компиляции:

var territories = db.Territories;
if (someCondition)
    territories = territories.Where(t => t.PendingUserCount > 0);
// Cannot implicitly convert 'System.Linq.IQueryable<Territory> to System.Data.Linq.Table<Territory>

Я тоже пытался дозвониться до db.Territories.ToList(), но безрезультатно.

Я уверен, что это просто неправильное понимание того, как работает Linq, но я был бы признателен, если бы кто-то мог мне помочь.

Ответы [ 9 ]

8 голосов
/ 15 апреля 2009

дБ. Территории возвращают объект таблицы. Следовательно, переменная будет иметь тип System.Data.Linq.Table. Позже вы попытаетесь (основываясь на каком-то условии) назначить что-то типа System.Linq.IQueryable переменной. Поскольку .NET строго типизирован, компилятор выдает ошибку.

Переменным типа var будет присвоен тип, когда они будут назначены первыми. Вот так я и пытаюсь вспомнить себя.

7 голосов
/ 15 апреля 2009

Для этого типа накопителя Where необходимо указать компилятору использовать IQueryable<T>:

IQueryable<Territory> territories = db.Territories;
if (someCondition)
    territories = territories.Where(t => t.PendingUserCount > 0);
... etc
5 голосов
/ 15 апреля 2009

Альтернатива:

var territories = db.Territories.AsQueryable();
if (someCondition)
    territories = territories.Where(t => t.PendingUserCount > 0);
3 голосов
/ 15 апреля 2009

изменить на это

var territories = db.Territories;

до

IQueryable territories = db.Territories.Where(t => t.PendingUserCount > 0);

Причина в том, что, вызывая db.Territories, вы получаете все данные обратно, возвращая их в объекте linq.table. Db.Territores.where (... вместо этого вернет объект IQueryable.

2 голосов
/ 15 апреля 2009

Одна из потенциально запутанных вещей, связанных с «var», заключается в том, что его тип определяется во время компиляции, поэтому вы не можете присвоить ему диапазон различных типов. Люди с опытом работы с динамическими языками, такими как Python, поначалу иногда смущаются этим.

1 голос
/ 15 апреля 2009

Ваш var territories первоначально набирается как System.Data.Linq.Table<Territory>, а затем вы пытаетесь присвоить ему результаты предложения Where (типа System.Linq.IQueryable<Territory>).

Помните, что компилятор выводит тип var при назначении, поэтому после его присвоения тип изменить нельзя.

Попробуйте что-то вроде этого:

System.Linq.IQueryable<Territory> territories;
if (someCondition)
    territories = db.Territories.Where(t => t.PendingUserCount > 0);
0 голосов
/ 15 апреля 2009

Вы не можете переназначить переменную другого типа после того, как вы объявили ее. Итак, ваше объявление var уже напечатало его в System.Data.Linq.Table.

Это когда-то огонь.

0 голосов
/ 15 апреля 2009

Вам нужно использовать тип IQueryable, как предлагали другие:

также этот запрос linq может также работать:

var query = from territories in db.Territories
            where territories.SomeProperty == SomeCondition
            where territories.PendingUserCount > 0
            select territories;
0 голосов
/ 15 апреля 2009

Поскольку вы ввели «var» в качестве таблицы <Territory>, а затем попытаетесь переназначить его как IQueryable <Territory>.

Это эквивалентно высказыванию

  var i = 0

  i = "a string";

РЕДАКТИРОВАТЬ: Чтобы уточнить, var неявно строго типизирован во время компиляции, а не во время выполнения, в отличие от динамически типизированного языка сценариев.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...