无法将SQL查询转换为等效的LinqToEntities代码?

时间:2012-06-09 13:28:57

标签: entity-framework tsql c#-4.0 linq-to-entities

简短: 总结这个问题的一种更简单的方法是,你可以对linq中的连接应用条件吗?

我有以下sql查询:

select cdm.cashID, cdm.DateTimeTillOpened, cdm.DateTimeTillClosed, o.OrderID, o.OrderDate
from CashDrawsMonies cdm
join Orders o on o.OrderDate >= cdm.DateTimeTillOpened
              AND o.OrderDate <= cdm.DateTimeTillClosed
join Users u on o.UserID = u.UserID
where u.UserID = 'C3763CC6-D1C5-4EF3-9B83-F7AB3BF8827A'
group by cdm.cashID, cdm.DateTimeTillOpened, cdm.DateTimeTillClosed, o.OrderID, o.OrderDate
order by o.OrderDate desc

备用SQL @

select *
from CashDrawsMonies cdm
where exists
(
    select * 
    from Orders o 
    join Users u on o.UserID = u.UserID
    where 
        o.OrderDate >= cdm.DateTimeTillOpened and 
        o.OrderDate <= cdm.DateTimeTillClosed and
        u.UserID = 'C3763CC6-D1C5-4EF3-9B83-F7AB3BF8827A'
)

我可以转换大多数查询但是在Linq中的连接它总是要求一个相等的关键字,而不是像> gt或=&lt; =这允许我在sql中为连接添加条件。这是什么让我头疼我怎么转换呢?

我的代码(c#)中的linq-To-Entites模型设置为:

Cache.Model.Orders
Cache.Model.CashDrawMonies
Cache.Model.Users

感谢帮助。

尝试1:

                var results = from o in Cache.Model.Orders
                          from c in Cache.Model.CashDrawMoneys
                          join u in Cache.Model.Users on o.UserID equals u.UserID
                          where c.DateTimeTillOpened >= o.OrderDate
                          && c.DateTimeTillClosed <= o.OrderDate
                          select c;

尝试2:

            var results = from c in Cache.Model.CashDrawMoneys
                          from o in Cache.Model.Orders
                          where c.DateTimeTillOpened >= o.OrderDate
                          && c.DateTimeTillClosed <= o.OrderDate
                          group c by new { c.cashID, c.DateTimeTillOpened, c.DateTimeTillClosed, o.OrderID, o.OrderDate, o.UserID } into temp
                          from t in temp
                          join u in Cache.Model.Users on t.UserID equals u.UserID
                          where t.UserID == selectedUser.UserID
                          select t;

不返回结果....:S

更新:

我重新编写了我的sql,sql的第二个内容正是我想知道的。只是需要有人为我转换它????

使用Linqer转换的SQL版本2:

from cdm in db.CashDrawMoneys
where
    (from o in db.Orders
    join u in db.Users on o.UserID equals u.UserID
    where
      o.OrderDate >= cdm.DateTimeTillOpened &&
      o.OrderDate <= cdm.DateTimeTillClosed &&
      u.UserID == new Guid("C3763CC6-D1C5-4EF3-9B83-F7AB3BF8827A")
    select new {
      o,
      u
    }).FirstOrDefault() != null
select new {
  cdm.UserID,
  cdm.DateTimeTillClosed,
  cdm.DateTimeTillOpened,
  cdm.LooseChange,
  cdm.Fivers,
  cdm.Tens,
  cdm.Twenties,
  cdm.Fifties,
  cdm.IsOpen,
  cdm.IsClosed,
  cdm.ClosingValue,
  cdm.OpeningValue,
  cdm.cashID
}

编译nbut会产生以下错误:

“DbIsNullExpression的参数必须引用基元或引用类型。”

2 个答案:

答案 0 :(得分:1)

第一次尝试的连接看起来是正确的。但你转过比较运算符了吗?

where c.DateTimeTillOpened **>=** o.OrderDate && c.DateTimeTillClosed **<=** o.OrderDate

<强>更新

您无法在LINQ2EF中创建新对象,因为它不知道如何将其转换为sql。

u.UserID == new Guid("C3763CC6-D1C5-4EF3-9B83-F7AB3BF8827A")

您必须在linq语句之前定义GUID,然后使用变量

var gid = new Guid("C3763CC6-D1C5-4EF3-9B83-F7AB3BF8827A")

from cdm in db.CashDrawMoneys
where
    (from o in db.Orders
    join u in db.Users on o.UserID equals u.UserID
    where
    o.OrderDate >= cdm.DateTimeTillOpened &&
    o.OrderDate <= cdm.DateTimeTillClosed &&
    u.UserID == gid

答案 1 :(得分:0)

以下是我设法得到的内容:

                var results = from cdm in Cache.Model.CashDrawMoneys
                          where (from o in Cache.Model.Orders
                                join u in Cache.Model.Users on o.UserID equals u.UserID
                                where o.OrderDate >= cdm.DateTimeTillOpened && o.OrderDate <= cdm.DateTimeTillClosed &&
                                    u.UserID == selectedUser.UserID
                                select o).FirstOrDefault() != null
                          select cdm;

它与你得到的非常接近,并且不必担心guid,因为它已经为我创建,因为我有一个'selectedUser'对象。

最后一行可能是:

                                    select o).Any()
                          select cdm;

但我并不感到兴奋,我得到了两个版本,但我会坚持使用我的第一个版本。