Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从LINQ生成的SQL不一致_C#_Linq_Plsql_Telerik Open Access - Fatal编程技术网

C# 从LINQ生成的SQL不一致

C# 从LINQ生成的SQL不一致,c#,linq,plsql,telerik-open-access,C#,Linq,Plsql,Telerik Open Access,我正在对ORACLE使用Telerik Open/Data Access ORM 为什么这两条语句会产生不同的SQL命令 声明#1 IQueryable<WITransmits> query = from wiTransmits in uow.DbContext.StatusMessages select wiTransmits; query = query.Where(e=>e.MessageID == id); 声明#2 IQueryable

我正在对ORACLE使用Telerik Open/Data Access ORM

为什么这两条语句会产生不同的SQL命令

声明#1

 IQueryable<WITransmits> query = from wiTransmits in uow.DbContext.StatusMessages
            select wiTransmits;

query = query.Where(e=>e.MessageID == id);
声明#2

 IQueryable<WITransmits> query = from wiTransmits in uow.DbContext.StatusMessages
            select new WITransmits
            {
                MessageID = wiTranmits.MessageID,
                Name = wiTransmits.Name
            };

query = query.Where(e=>e.MessageID == id);

使用第二条语句#2生成的查询返回表中的所有记录,而我只需要一条记录。数以百万计的记录使这一点成为禁忌。

第一个查询返回定义的完整对象,因此任何附加限制(如
Where
)都可以在实际运行之前附加到它。因此,可以如您所示组合查询

第二个返回一个新对象,它可以是任何类型,也可以包含任何信息。因此,查询将作为“返回所有内容”发送到数据库,并且在创建对象之后,除了与
Where
子句匹配的对象之外,所有对象都将被丢弃

尽管两者的类型相同,但想想这种情况:

var query = from wiTransmits in uow.DbContext.StatusMessages
    select new WITransmits
    {
        MessageID = wiTranmits.MessageID * 4 - 2,
        Name = wiTransmits.Name
    };
现在如何组合
Where
查询?当然,您可以在新对象创建过程中遍历代码并尝试将其移到外部,但由于可能存在任何问题,因此这是不可行的。如果检查是某种查找功能,该怎么办?如果它不是确定性的呢


因此,如果您基于数据库对象创建新对象,将有一个边界,在该边界中检索对象,然后在内存中执行进一步的查询。

Telerik Data Access将尝试将每个查询拆分为数据库端和客户端(或内存LINQ,如果您愿意)。
使用
select new
进行投影肯定会触发LINQ表达式树中的所有内容在投影后转到客户端。
这意味着在第二种情况下,您的LINQ查询效率低下,因为内存中应用了任何筛选,并且您已经传输了大量不必要的数据。

如果您希望以案例2中的方式编写LINQ表达式,您可以将
Select
子句追加到last,或者将结果显式转换为
IEnumerable
,以使任何进一步的处理都可以在内存中完成。

看起来像是ORM将投影作为
IEnumerable
返回。在第一条语句之后的两种情况下,查询的类型是什么?它们都是IQueryable(更新的原始帖子)和具体类型?这不是PL/SQL问题。我想你的意思是。在一个类似ORM的实体框架中,整个表达式——包括
wiTranmits.MessageID*4-2
——将被翻译成SQL,因此按
MessageID
排序/过滤也将显示在查询中。我认为Telerik在这里有一个不同的策略。也许更好的检查方法是MessageID=LocalFunction(wiTransmits.MessageID),
SELECT 
    a."MESSAGE_ID" COL1, 
   -- additional fields
FROM "XFE_REP"."WI_TRANSMITS" a 
var query = from wiTransmits in uow.DbContext.StatusMessages
    select new WITransmits
    {
        MessageID = wiTranmits.MessageID * 4 - 2,
        Name = wiTransmits.Name
    };