2013-12-02 6 views
2


У меня есть таблица с партией, и я использую ее через сущность.Как заставить Entity Framework генерировать отдельные предложения WHERE?

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
ВТОРАЯ имеет план выполнения со степенью параллельности 1 и оценочную стоимость поддерева ~ 2,5

Если я использую IQueryable как

query.Where(test=>test.COL2 == "CASE0") 
    .Where(test=>test.COL3 == "D240") 

EF concatenates where clauses и генерирует запрос типа FIRST. Можно ли принудительно генерировать запрос сущности, как SECOND?

PS: Я использую EF 4.4 и MSSQL 2008 R2

С наилучшими пожеланиями,
Роман

ответ

0

Если вы не хотите использовать сгенерированный SQL в рамках объекта на основе ваших LINQ, вы можете использовать эти параметры:

  1. Измените запрос на linq, к сожалению, это не поможет в вашем конкретном сценарии.

  2. Использовать низкоуровневые сущностные запросы под названием EntitySql, но это тоже не поможет.

  3. Используйте свой собственный 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-запросы намного лучше, чем версии для предварительного просмотра.

Успехов

Смежные вопросы