2016-11-03 21 views
0

プロジェクトでEF 6.0コードを最初に使用し、TPH継承を使用します。私は私のクラスで列挙型フィールドを使用する場合、EFは鋳造とSQL文を生成することを確認します。したがって、クエリが非常に遅く実行され、パフォーマンスが低下します。 SQLクエリでキャストを削除するにはどうすればよいですか?Entity Framework 6 TPH継承列挙型フィールド低速クエリを生成

ありがとうございました。

var db = new AppContext(); 
var p = db.Products.FirstOrDefault(x => x.ProdId == 1); 


public enum MyEnum 
{ 
    Field1 = 1, 
    Field2 = 2 
} 

public class Product 
{ 
    [Key] 
    public int ProdId { get; set; } 

    public string ProdName { get; set; } 

    //I run my code with this property and without this property. 
    //public MyEnum MyEnum { get; set; } 
} 

public class Chair : Product 
{ 
    public string ChairProp1 { get; set; } 
} 

public class Seat : Product 
{ 
    public string SeatProp1 { get; set; } 
} 

//EF generate this SQL without enum field. This is good SQL statements. 
SELECT TOP (1) 
[Extent1].[Discriminator] AS [Discriminator], 
[Extent1].[ProdId] AS [ProdId], 
[Extent1].[ProdName] AS [ProdName], 
[Extent1].[ChairProp1] AS [ChairProp1], 
[Extent1].[SeatProp1] AS [SeatProp1] 
FROM [dbo].[Products] AS [Extent1] 
WHERE ([Extent1].[Discriminator] IN (N'Chair',N'Seat',N'Product')) AND (1 = [Extent1].[ProdId]) 


//EF generate this SQL with enum field (myenum). there is alot of casting.i want to remove casting. 
SELECT 
[Limit1].[C1] AS [C1], 
[Limit1].[ProdId] AS [ProdId], 
[Limit1].[ProdName] AS [ProdName], 
[Limit1].[MyEnum] AS [MyEnum], 
[Limit1].[C2] AS [C2], 
[Limit1].[C3] AS [C3] 
FROM (SELECT TOP (1) 
    [Extent1].[ProdId] AS [ProdId], 
    [Extent1].[ProdName] AS [ProdName], 
    [Extent1].[MyEnum] AS [MyEnum], 
    CASE WHEN ([Extent1].[Discriminator] = N'Product') THEN '0X' WHEN ([Extent1].[Discriminator] = N'Chair') THEN '0X0X' ELSE '0X1X' END AS [C1], 
    CASE WHEN ([Extent1].[Discriminator] = N'Product') THEN CAST(NULL AS varchar(1)) WHEN ([Extent1].[Discriminator] = N'Chair') THEN [Extent1].[ChairProp1] END AS [C2], 
    CASE WHEN ([Extent1].[Discriminator] = N'Product') THEN CAST(NULL AS varchar(1)) WHEN ([Extent1].[Discriminator] = N'Chair') THEN CAST(NULL AS varchar(1)) ELSE [Extent1].[SeatProp1] END AS [C3] 
    FROM [dbo].[Products] AS [Extent1] 
    WHERE ([Extent1].[Discriminator] IN (N'Chair',N'Seat',N'Product')) AND (1 = [Extent1].[ProdId]) 
) AS [Limit1] 
+0

6.1.3にアップグレードできますか? –

答えて

0

ディスクリミネータの設定が間違っているようです。

public class ChairConfig : EntityTypeConfiguration<Chair> 
{ 
    public ChairConfig() 
    { 
     this.Map(m => m.Requires(discriminator: "MyEnum").HasValue(MyEnum.Field1)); 
    } 
} 

public class SeatConfig : EntityTypeConfiguration<Seat> 
{ 
    public SeatConfig() 
    { 
     this.Map(m => m.Requires(discriminator: "MyEnum").HasValue(MyEnum.Field2)); 
    } 
} 

そしてクエリで、あなたは同様に取得したいタイプを指定する必要があります:あなたはこのように流暢なAPIでそれを行うことができます

、弁別し、どのようなことのタイプだとするフィールドを指定する必要がありますこれは

var db = new AppContext(); 
var p = db.Products.OfType<Chair>().FirstOrDefault(x => x.ProdId == 1); 
+0

いいえ、これは問題ではありません。ご覧のように、弁別者に質問されます。 –

関連する問題