【问题标题】:SQL Linq QuestionSQL Linq 问题
【发布时间】:2010-08-11 13:11:19
【问题描述】:

我在 ms SQL 2008 中有以下有效的 TSQL 查询

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 查询?

更新: 我根据 David B 的建议修改了 LINQ 查询。

我仍然收到以下错误: “使用 UNION、INTERSECT 或 EXCEPT 运算符组合的所有查询必须在其目标列表中具有相同数量的表达式。”

【问题讨论】:

  • 您的查询出了什么问题?
  • 1.分组错误“使用 UNION、INTERSECT 或 EXCEPT 运算符组合的所有查询必须在其目标列表中具有相等数量的表达式。” 2. 关于不允许的空值的错误 3. 关于 kg.Count() 的错误,“无法将 int 转换为 bool”。

标签: c# sql-server linq tsql linq-to-sql


【解决方案1】:

大卫对前两个问题的看法是正确的。对于您的最后一个问题 (3),Count() 不像在 SQL 中那样工作。它需要一个返回布尔值的谓词。您将它与整数一起使用(即 z.click、z.sales 等)

【讨论】:

    【解决方案2】:

    问题是投影中的匿名类型不相同... ID 是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)


    好的,显然您遇到了 here 所述的错误翻译行为。

    发生的事情是 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 
            };
    

    如果您有超过 2 列要清空,您可以使用减法、除法、乘法等方法。

    【讨论】:

    • 感谢帮助,我尝试这样做,你可以在上面看到我更新的代码,我仍然收到错误。
    • 是的,我看到查询的翻译方式错误。我尝试了您的解决方案,但我不确定我是否了解如何将其应用于其余表格(销售、潜在客户..)。哇,这比我想象的要难。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多