我有一个分区表,我通过实体框架使用它。
CREATE PARTITION FUNCTION PART_FN (NVARCHAR(10))
AS RANGE LEFT FOR VALUES ('CASE0');
CREATE PARTITION SCHEME PART_SCH
AS
PARTITION PART_FN
ALL TO ([PRIMARY]);
CREATE TABLE TEST_PART(ID INT NOT NULL PRIMARY KEY NONCLUSTERED ON [PRIMARY] IDENTITY, COL2 NVARCHAR(10), COL3 NVARCHAR(10))
ON PART_SCH(COL2);
DECLARE @C INT = 1000000;
SET IDENTITY_INSERT TEST_PART ON;
WITH
A AS (SELECT 1 AS N
UNION ALL
SELECT N+1 FROM A WHERE N < @C)
INSERT INTO TEST_PART(ID, COL2, COL3)
SELECT ID, COL2, COL3 FROM(
SELECT N AS ID,
'CASE' + CONVERT(NVARCHAR(10), CASE WHEN N%20 = 0 THEN 0 ELSE 1 END) AS COL2,
'D' + CONVERT(NVARCHAR(10), N, 0) AS COL3 FROM A) AS A
OPTION (MAXRECURSION 0);
SET IDENTITY_INSERT TEST_PART OFF;
我选择了两个选择:
SELECT * FROM TEST_PART WHERE COL2='CASE0' AND COL3='D240';
SELECT * FROM (SELECT * FROM TEST_PART WHERE COL2='CASE0') AS A WHERE COL3='D240';
他们看起来一样
但是!
FIRST具有度并行度4的执行计划和估计的子树成本~5
SECOND具有程度并行性1的执行计划和估计的子树成本~2.5
如果我像
一样使用IQueryablequery.Where(test=>test.COL2 == "CASE0")
.Where(test=>test.COL3 == "D240")
EF连接where子句并生成类似FIRST的查询。
是否有可能强制实体框架生成查询,如SECOND?
PS:我使用EF 4.4和MSSQL 2008 R2
最好的问候,
罗马
答案 0 :(得分:0)
如果您不想基于linq使用生成的实体框架SQL,可以使用以下选项:
更改您的linq查询,遗憾的是,这在您的特定情况下无济于事。
使用名为 EntitySql 的低级实体框架查询,但这也无济于事。
使用您自己的SQL,但不要失去变更跟踪,对象实现和实体框架的其他好处的好处
为此,您可以使用以下代码:
class Program
{
static void Main(string[] args)
{
using (var appDb = new AppDb())
{
var peopleFromCustomQuery = appDb.People.SqlQuery("select Id , Name from People");
// OR
peopleFromCustomQuery = appDb.Set<Person>().SqlQuery("select Id , Name from People");
}
}
}
public class Person
{
public Int32 Id { get; set; }
public String Name { get; set; }
}
public class AppDb : DbContext
{
public DbSet<Person> People { get; set; }
}
最后,我建议你使用最新版本的实体框架,它生成的sql查询远比它的预览版本好。
祝你好运