Tsql 将T-SQL转换为Linq

Tsql 将T-SQL转换为Linq,tsql,entity-framework-4,linq-to-entities,Tsql,Entity Framework 4,Linq To Entities,我正在使用EntitryFramework4.1,我正在努力理解如何将下面使用连接和聚合方法的查询转换为DomainService中的LINQtoEntities调用 SELECT tblTime.Period As Timeline, COUNT(tblEngineeringDashboard_ItemList.ID) AS Items FROM tblEngineeringDashboard_ItemList INNER JOIN

我正在使用EntitryFramework4.1,我正在努力理解如何将下面使用连接和聚合方法的查询转换为DomainService中的LINQtoEntities调用

SELECT     tblTime.Period As Timeline, COUNT(tblEngineeringDashboard_ItemList.ID) AS Items
FROM         tblEngineeringDashboard_ItemList INNER JOIN
                      tblTime ON tblEngineeringDashboard_ItemList.TimeID = tblTime.ID
GROUP BY tblTime.Period
ORDER BY tblTime.Period
有人能提供帮助吗

可能的解决办法

Dim var = From i In ObjectContext.tblEngineeringDashboard_ItemList
                Join t In ObjectContext.tblTimes On i.TimeID Equals t.ID
                Group By i.TimeID Into Group
                Select DateStart = (From n In ObjectContext.tblTimes Where n.ID = TimeID Select n.Period), PartCount = Group.Count
菲尔:这行吗

tblEngineeringDashboard_ItemList
    .Join(tblTime,ed => ed.TimeID ,t => t.ID, (ed,t) => new{ed,t})
.GoupBy(g => g.t.Period)
.Select(s => new 
          {
           Timeline = s.Key,
           Items = s.Count()
          }
       )
.OrderBy(o => o.Timeline)
这行吗

tblEngineeringDashboard_ItemList
    .Join(tblTime,ed => ed.TimeID ,t => t.ID, (ed,t) => new{ed,t})
.GoupBy(g => g.t.Period)
.Select(s => new 
          {
           Timeline = s.Key,
           Items = s.Count()
          }
       )
.OrderBy(o => o.Timeline)

虽然从sql转换为linq不是一种理想的方法(您应该直接在linq中思考,将您的需求转换为linq查询),但您发布的查询相当简单

var grouped = tblTime.OrderBy(c => c.Period).GroupBy(c => c.Period).Select(c =>
new {
       timeline = c.Key,
       count = c.SelectMany(x => x.tblEngineeringDashboard).Count()
    });
*编辑:好了,修正了。L2E引擎上的一切


这提供了表之间有正确的外键(因此您不必手动声明联接)。

虽然从sql转换为linq不是一种理想的方法(您应该直接在linq中思考,将您的需求转换为linq查询),但您发布的查询相当简单

var grouped = tblTime.OrderBy(c => c.Period).GroupBy(c => c.Period).Select(c =>
new {
       timeline = c.Key,
       count = c.SelectMany(x => x.tblEngineeringDashboard).Count()
    });
*编辑:好了,修正了。L2E引擎上的一切


如果表之间有正确的外键(因此不必手动声明联接)。

首先想到的是:

var q = from t in Context.Time
        group t by t.Period into g
        orderby g.Key
        select new 
        {
            Timeline = g.Key,
            Items = (from ti in g
                     from il in ti.ItemList // or whatever the property for the navigation to tblEngineeringDashboard_ItemList is called
                     select il).Count()
        };
但是,原始SQL有一个
内部联接
,它将拒绝
tblTime
记录,而
tblEngineeringDashboard\u ItemList
中没有任何匹配的记录。因此,您可能需要:

var q = from t in Context.Time
        where t.ItemList.Any()
        group t by t.Period into g
        orderby g.Key
        select new 
        {
            Timeline = g.Key,
            Items = (from ti in g
                     from il in ti.ItemList // or whatever the property for the navigation to tblEngineeringDashboard_ItemList is called
                     select il).Count()
        };
您还可以翻转查询:

var q = from i in Context.EngineeringDashboardItemList
        where i.Time != null 
        group i by i.Time.Period into g
        orderby g.Key
        select new 
        {
            Timeline = g.Key,
            Items = g.Count()
        };

首先想到的是:

var q = from t in Context.Time
        group t by t.Period into g
        orderby g.Key
        select new 
        {
            Timeline = g.Key,
            Items = (from ti in g
                     from il in ti.ItemList // or whatever the property for the navigation to tblEngineeringDashboard_ItemList is called
                     select il).Count()
        };
但是,原始SQL有一个
内部联接
,它将拒绝
tblTime
记录,而
tblEngineeringDashboard\u ItemList
中没有任何匹配的记录。因此,您可能需要:

var q = from t in Context.Time
        where t.ItemList.Any()
        group t by t.Period into g
        orderby g.Key
        select new 
        {
            Timeline = g.Key,
            Items = (from ti in g
                     from il in ti.ItemList // or whatever the property for the navigation to tblEngineeringDashboard_ItemList is called
                     select il).Count()
        };
您还可以翻转查询:

var q = from i in Context.EngineeringDashboardItemList
        where i.Time != null 
        group i by i.Time.Period into g
        orderby g.Key
        select new 
        {
            Timeline = g.Key,
            Items = g.Count()
        };


完全不是。例如,该计数将给出按某个键分组的tblTime行数,而不是按该键分组的所有项下外键表的总行数。检查我的答案。我可能弄错了,但是如果它是一个内部联接,它不应该返回正确的行数吗?在他的sql查询中,他正在计算联接提供的元素。在linq中转换为selectmany。如果他正在计算查询返回的行数,那么您的方法是正确的。完全不是。例如,该计数将给出按某个键分组的tblTime行数,而不是按该键分组的所有项下外键表的总行数。检查我的答案。我可能弄错了,但是如果它是一个内部联接,它不应该返回正确的行数吗?在他的sql查询中,他正在计算联接提供的元素。在linq中转换为selectmany。如果他正在计算查询返回的行数,那么您的方法是正确的,这将为您提供n+1个查询,假定已启用延迟加载。如果禁用了延迟加载,那么
Count()
将是错误的。是的,我假设lazyloading处于启用状态,因为我总是使用它。我应该指定的。不过,n+1仍然是个问题。你会得到正确的答案。。。最终,我看不出n+1的问题。这种查询我做了很多次都没有遇到任何问题。请在SQL profiler中尝试。您正在懒洋洋地加载
c.tblEngineeringDashboard
。更糟糕的是,您正在加载单个记录,而不仅仅是计数。枚举
分组
将结果带入对象空间;您已经离开了L2E,
Count()
不能再被推回到SQL
Count
。该SQL
Count
将为您提供n+1个查询,假定延迟加载已打开。如果禁用了延迟加载,那么
Count()
将是错误的。是的,我假设lazyloading处于启用状态,因为我总是使用它。我应该指定的。不过,n+1仍然是个问题。你会得到正确的答案。。。最终,我看不出n+1的问题。这种查询我做了很多次都没有遇到任何问题。请在SQL profiler中尝试。您正在懒洋洋地加载
c.tblEngineeringDashboard
。更糟糕的是,您正在加载单个记录,而不仅仅是计数。枚举
分组
将结果带入对象空间;你已经离开了L2E,
Count()。。。。。Dim var=From i In ObjectContext.tblEngineeringDashboard_ItemList将t In ObjectContext.tblTimes On i.TimeID等于t.ID Group By i.TimeID加入组Select DateStart=(From n In ObjectContext.tblTimes其中n.ID=TimeID选择n.Period),PARTCUNT=Group.Count在LINQ to Entities或LINQ to SQL中使用
Join()
。理解,但在创建笛卡尔积时使用交叉联接时需要小心。这是一个跨越所有可能性的未定义连接。但是LINQ更容易阅读。当使用LINQ进行实体导航时,不存在意外创建笛卡尔积的危险。事实上,他们的优势之一是不可能破坏
加入
条件(“code>ON
”)。嗨,Craig,我接受了你的解决方案,在改变了一些东西后,它开始工作了,但我不确定我是否理解为什么或者我的解决方案是最好的。。。。。Dim var=From i In ObjectContext.tblEngineeringDashboard_ItemList将t In ObjectContext.tblTimes On i.TimeID等于t.ID Group By i.TimeID加入组Select DateStart=(From n In ObjectContext.tblTimes其中n.ID=TimeID选择n.Period),PARTCUNT=Group.Count在LINQ to Entities或LINQ to SQL中使用
Join()
。理解,但在创建笛卡尔积时使用交叉联接时需要小心。这是一个跨越所有可能性的未定义连接。但是LINQ更容易阅读。当使用LINQ进行实体导航时,不存在意外创建笛卡尔积的危险。事实上,他们的优势之一是这是不可能的