SQL Linq Вопрос - PullRequest
       6

SQL Linq Вопрос

0 голосов
/ 11 августа 2010

У меня есть следующий рабочий запрос TSQL в MS SQL 2008

SELECT
    Date,
    COUNT(click) AS clicks,
    COUNT(sale) AS sales,
    count(lead) as leads
FROM
(
SELECT ClickDate as date ,ID AS click ,CAST(NULL AS int) AS  sale , CAST(null as int) as lead
FROM clicks

UNION ALL

SELECT Date,null, ID ,NULL
FROM sales

UNION ALL

SELECT Date,null, NULL ,ID
FROM leads

) t
GROUP BY Date

Как мне преобразовать это в LINQ to SQL? Я написал этот LINQ, но он не работает.

public class mydata
{
    public DateTime date { get; set; }
    public int? click { get; set; }
    public int? sale { get; set; }
    public int? lead { get; set; }
}

var clicks = from c in Clicks
             select new mydata
             { 
                 date = c.ClickDate, click = c.ID,  sale = null, lead = null
             };

var sales = from s in Sales
            select new mydata
            {
                 date = s.Date, click = null, sale = s.ID, lead = null
            };

var leads = from l in Leads
            select new mydata
            {
                date = l.Date, click = null, sale = null, lead = l.ID
            };

var v = clicks.Concat(sales).Concat(leads);

var res = from x in v
       group x by x.date into xg
       select new
       {
                 date = xg.Key, clicks = xg.Count(z => z.click != null)
       };
}

Как мне исправить этот запрос LINQ?

Обновление: Я изменил запрос LINQ, основываясь на рекомендации Дэвида Б.

Я все еще получаю следующую ошибку: «Все запросы, объединенные с использованием оператора UNION, INTERSECT или EXCEPT, должны иметь одинаковое количество выражений в своих целевых списках».

Ответы [ 2 ]

0 голосов
/ 11 августа 2010

Дэвид прав насчет первых двух вопросов.Для вашей последней проблемы (3), Count () не работает, как в SQL.Ожидается предикат, который возвращает бул.Вы используете его с целыми числами (iezclick, z.sales и т. Д.)

0 голосов
/ 11 августа 2010

Проблема в том, что анонимные типы в проекциях не идентичны ... Идентификатор: int в одном и Nullable<int> в другом.

Вместо использования анонимного типа в ваших проекциях используйте:

public class ConcatTarget
{
  public DateTime TheDate {get;set;}
  public int? ID {get;set;}
  public string sale {get;set;}
  public string lead {get;set;}
}

Несмотря на то, что экземпляры фактически не создаются, LinqToSql использует форму класса для перевода запроса.

Что касается Count, возможно, вы имели в виду .Count(x => x.Prop != null)?


Хорошо, очевидно, вы столкнулись с ошибочным поведением перевода, как описано здесь .

То, что происходит, - переводчик sql видит нулевые назначения и выбрасывает их. Это приводит к тому, что между наборами выбирается неверное количество столбцов sql.

Вот возможный обходной путь:

int? myNull = null;

var clicks =
  from c in Clicks 
  select new mydata 
  {  
    date = c.ClickDate,
    click = c.ID,
    sale = c.ID + myNull,
    lead = myNull + c.ID  //note - expressions must be unique
  }; 

Основная идея заключается в создании уникальных выражений, которые переводчик запросов не может выбросить. Это сложнее, чем кажется (выше моя девятая попытка).


Вот две другие таблицы:

var sales = from s in Sales 
        select new mydata 
        { 
             date = s.Date,
             click = s.ID + myNull,
             sale = s.ID,
             lead = myNull + s.ID
        }; 

var leads = from l in Leads 
        select new mydata 
        { 
            date = l.Date,
            click = l.ID + myNull,
            sale = myNull + l.ID,
            lead = l.ID 
        };

Если у вас более двух столбцов, которые нужно обнулять, вы можете прибегнуть к вычитанию, делению, умножению и т. Д.

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