2017-01-09 51 views
4

我有這樣的SQL查詢,其工作原理:SQL> LINQ到SQL中,SQL查詢的工作,LINQ到SQL返回空數據集

select sum(dbos.Points) as Points, dboseasons.Year 
    from dbo.StatLines dbos 
    inner join dbo.Games dbog on dbog.GameId = dbos.GameId 
    inner join dbo.Seasons dboseasons on dbog.Season_SeasonId = dboseasons.SeasonId 
    where dbos.PlayerId = 3 
    group by dboseasons.Year 

,則返回點,年份(56,2016)

我試圖將其轉換爲Linq查詢以與EF一起使用。

var query = 
      from dbostats in _db.StatLines 
      join dbogames in _db.Games on dbostats.GameId equals dbogames.GameId 
      join dboseasons in _db.Seasons on dbogames.Season.SeasonId equals dboseasons.SeasonId 
      where dbostats.PlayerId == player.PlayerId 
      group dbostats.Points by dboseasons.Year into g 
      select new 
      { 
       Year = g.Key, 
       Points = g.Sum() 
      }; 

     playerAndStatLines.StatLinesBySeason = 
      query 
      .ToList() 
      .Select(r => new StatsBySeason 
       { 
        Season = r.Year, 
        Points = r.Points 
       }); 

它返回一個空的結果集。

當我查看SQL其發電,它的這種

SELECT 
[GroupBy1].[K1] AS [Year], 
[GroupBy1].[A1] AS [C1] 
FROM (SELECT 
    [Extent3].[Year] AS [K1], 
    SUM([Extent1].[Points]) AS [A1] 
    FROM [dbo].[StatLines] AS [Extent1] 
    INNER JOIN [dbo].[Games] AS [Extent2] ON [Extent1].[GameId] = [Extent2].[GameId] 
    INNER JOIN [dbo].[Seasons] AS [Extent3] ON [Extent2].[Season_SeasonId] = [Extent3].[SeasonId] 
    WHERE ([Extent1].[Discriminator] IN (N'StatsBySeason',N'StatLines')) AND ([Extent1].[PlayerId] = 3) 
    GROUP BY [Extent3].[Year] 
) AS [GroupBy1] 

其中,符合市場預期,當針對我的數據庫執行返回一個空的結果集。

的問題似乎是這一點:

([Extent1].[Discriminator] IN (N'StatsBySeason',N'StatLines')) AND 

如果我參加了這一點,並運行生成的查詢,然後我回到我的2016年,56的結果。

這是什麼Extent1.Discriminator,它爲什麼從我的linq查詢生成它?

我的模型類:

public class PlayerAndStatLines 
    { 
     public PlayerWithTeam PlayerWithTeam { get; set; } 
     public IEnumerable<StatsBySeason> StatLinesBySeason { get; set; } 
    } 


public class Season 
    { 
     public int SeasonId { get; set; } 
     public int Year { get; set; } 
    } 


public class Game 
    { 
     public int GameId { get; set; } 
     public int HomeTeamId { get; set; } 
     public int AwayTeamId { get; set; } 
     public int HomeScore { get; set; } 
     public int AwayScore { get; set; } 
     public DateTime DatePlayed { get; set; } 
     public GameType GameType { get; set; } 
     public int? PlayoffGameNumber { get; set; } 
     public Season Season { get; set; } 
    } 

public class StatLines 
    { 
     public int StatLinesId { get; set; } 
     public int GameId { get; set; } 
     public int PlayerId { get; set; } 
     public int TeamId { get; set; } 
     public int Points { get; set; } 
     public int DefensiveRebounds { get; set; } 
     public int OffensiveRebounds { get; set; } 
     public int Assists { get; set; } 
     public int Turnovers { get; set; } 
     public int Minutes { get; set; } 
     public int Steals { get; set; } 
     public int Blocks { get; set; } 
     public int Fouls { get; set; } 
     public int ThreePointFieldGoalsAttempted { get; set; } 
     public int ThreePointFieldGoalsMade { get; set; } 
     public int TwoPointFieldGoalsAttempted { get; set; } 
     public int TwoPointFieldGoalsMade { get; set; } 
     public int FreeThrowsMade { get; set; } 
     public int FreeThrowsAttempted { get; set; } 
     public bool Started { get; set; } 
    } 


public class StatsBySeason : StatLines 
    { 
     public int Season { get; set; } 

     public string SeasonYears => Season + "/" + (Season + 1); 
    } 

如果我運行下面的SQL:

select Discriminator from dbo.StatLines 

我得到2排回,都是空的。

謝謝。

+3

Discriminator是由Entity Framework添加的一列,用於在模型形成繼承層次結構時持久化對象的具體類型。你可以將模型類添加到問題中嗎? –

+0

看起來像'StatsBySeason'類繼承了'StatLines'實體,對嗎? –

+0

@Ivan Stoev - 這是正確的。我將我的模型類添加到OP – Stuart

回答

2

在同一個程序集內繼承一個實體類時要非常小心(如果可能,避免)。 EF會發現派生類,並決定要使用TPH inheritance strategy並以靜默方式(如果您使用自動遷移)創建並使用Discriminator列,這對於現有數據當然是空的,並且會打破查詢。

我看到兩個選項:

  • 替換繼承與遏制:

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
        modelBuilder.Ignore<StatsBySeason>(); 
        // ... 
    } 
    

    或數據註釋:

    public class StatsBySeason 
    { 
        public int Season { get; set; } 
        public StatLines StatLines { get; set; } 
    
        public string SeasonYears => Season + "/" + (Season + 1); 
    } 
    
  • 讓EF用流利的配置忽略StatsBySeason類:

    [NotMapped] 
    public class StatsBySeason : StatLines 
    { 
        // ... 
    } 
    
+0

謝謝,我並不知道TPH的繼承。你的解決方案工作,我會去第一個我認爲:) – Stuart

+0

Got gotcha陷入困境。 – bbsimonbb