如何强制实体框架生成单独的WHERE子句?

时间:2013-12-02 06:05:15

标签: sql-server entity-framework partitioning


我有一个分区表,我通过实体框架使用它。

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

如果我像

一样使用IQueryable
query.Where(test=>test.COL2 == "CASE0")
    .Where(test=>test.COL3 == "D240")

EF连接where子句并生成类似FIRST的查询。 是否有可能强制实体框架生成查询,如SECOND?

PS:我使用EF 4.4和MSSQL 2008 R2

最好的问候,
罗马

1 个答案:

答案 0 :(得分:0)

如果您不想基于linq使用生成的实体框架SQL,可以使用以下选项:

  1. 更改您的linq查询,遗憾的是,这在您的特定情况下无济于事。

  2. 使用名为 EntitySql 的低级实体框架查询,但这也无济于事。

  3. 使用您自己的SQL,但不要失去变更跟踪,对象实现和实体框架的其他好处的好处

  4. 为此,您可以使用以下代码:

    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查询远比它的预览版本好。

    祝你好运