Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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
Linq 为什么这些查询会生成不同的sql?_Linq_Entity Framework - Fatal编程技术网

Linq 为什么这些查询会生成不同的sql?

Linq 为什么这些查询会生成不同的sql?,linq,entity-framework,Linq,Entity Framework,我对实体框架中的linq查询有问题。我正在查询导航属性上的字段。问题是生成的sql不是最优的。下面的例子被简化了,实际上我正在尝试传递一个表达式树,这就是为什么第二个带有let绑定的查询不是一个足够的解决方案,即使生成的sql是我想要的 总之,我有两个问题: 为什么生成的sql不同?有没有办法生成一个sql查询,它不会为每个具有表达式树的条件创建联接 更新:当我第一次发布问题时,我意识到我在第一个查询中包含了(“证券”),而不是第二个查询,但这不会改变标准的应用方式,只会改变选择的列。 var

我对实体框架中的linq查询有问题。我正在查询导航属性上的字段。问题是生成的sql不是最优的。下面的例子被简化了,实际上我正在尝试传递一个表达式树,这就是为什么第二个带有let绑定的查询不是一个足够的解决方案,即使生成的sql是我想要的

总之,我有两个问题:

为什么生成的sql不同?有没有办法生成一个sql查询,它不会为每个具有表达式树的条件创建联接

更新:当我第一次发布问题时,我意识到我在第一个查询中包含了(“证券”),而不是第二个查询,但这不会改变标准的应用方式,只会改变选择的列。

var qry = db.Positions                   
    .Where(criteria)
    .ToList();

var qry1 = (from p in db.Positions
            where p.Security.Country == "NO" || p.Security.Country == "US" || p.Security.Country == "GB"
            select p).ToList();

var qry2 = (from p in db.Positions
           let s = p.Security
           where s.Country == "NO" || s.Country == "US" || s.Country == "GB"
           select p).ToList();


--qry1
SELECT 
    [Extent1].* --All columns from tblPositions
    FROM     [dbo].[tblPositions] AS [Extent1]
    LEFT OUTER JOIN [dbo].[tblSecurities] AS [Extent2] ON ([Extent2].[SecurityType] IN (1,2..)) AND ([Extent1].[Security] = [Extent2].[SecuritySeq])
    LEFT OUTER JOIN [dbo].[tblSecurities] AS [Extent3] ON ([Extent3].[SecurityType] IN (1,2..)) AND ([Extent1].[Security] = [Extent3].[SecuritySeq])
    LEFT OUTER JOIN [dbo].[tblSecurities] AS [Extent4] ON ([Extent4].[SecurityType] IN (1,2..)) AND ([Extent1].[Security] = [Extent4].[SecuritySeq])
    LEFT OUTER JOIN [dbo].[tblSecurities] AS [Extent5] ON ([Extent5].[SecurityType] IN (1,2..)) AND ([Extent1].[Security] = [Extent5].[SecuritySeq])
    WHERE [Extent2].[Country] = 'NO' OR [Extent3].[Country] = 'US' OR [Extent4].[Country] = 'GB'

--qry2
SELECT 
    [Extent1].*
    FROM  [dbo].[tblPositions] AS [Extent1]
    LEFT OUTER JOIN [dbo].[tblSecurities] AS [Extent2] ON ([Extent2].[SecurityType] IN (1,2..)) AND ([Extent1].[Security] = [Extent2].[SecuritySeq])
    WHERE [Extent2].[Country] IN ('NO','US','GB')
在您的第一个查询中

var qry1 = (from p in db.Positions.Include("Security")
           where p.Security.Country == "NO" 
             || p.Security.Country == "US"
             || p.Security.Country == "GB"
           select p).ToList();
您似乎假设实体框架具有神奇的功能,可以推断生成的表达式树中的每个
语句都位于同一个对象上,并且可以将它们组合成一个contains。到目前为止,它还没有那么聪明

此外,两个查询返回的行不相同。第二个还需要一个include,以包含来自security的行(如果需要)。否则,您可以从第一个查询中删除它们(include only意味着返回行,这与where子句过滤行的能力无关)

或者让它更加面向对象和可读

var allowedCountries = new List<string>() { "NO, "US", "GB" };

var qry1 = (from p in db.Positions
            // I'm not sure if this is exactly correct
            where p.Security.Country in allowedCountries
            select p).ToList();

你是对的;对EF的要求可能太高了。然而,我在设计器中指定的关系告诉实体框架,每个位置应该只有一个安全性。这是哪个EF版本?
var qry1 = db.Positions
           .Where(p => allowedCountries.Contains(p.Security.Country))
           .ToList();