【问题标题】:SQL > Linq to Sql, SQL Query works, Linq to SQL returns empty data setSQL > Linq to Sql,SQL Query 工作,Linq to SQL 返回空数据集
【发布时间】:2017-01-09 13:35:26
【问题描述】:

我有这个有效的 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 行,都是空的。

谢谢。

【问题讨论】:

  • 鉴别器是实体框架添加的一列,用于在模型形成继承层次结构时保留对象的具体类型。您可以将您的模型类添加到问题中吗?
  • 看起来您的 StatsBySeason 类正在继承 StatLines 实体,对吗?
  • @Ivan Stoev - 这是正确的。我会将我的模型类添加到 OP
  • [Extent1].[Discriminator] IN (N'StatsBySeason',N'StatLines') 省略的行的Discriminator 列的值是多少?
  • @chris-pickford,我该如何找到它?这不是我添加到表格中的列。

标签: c# entity-framework linq


【解决方案1】:

在同一个程序集中继承实体类时要非常小心(尽可能避免)。 EF 发现派生类并决定您要使用 TPH inheritance strategy 并静默(如果您正在使用自动迁移)创建和使用 Discriminator 列,对于现有数据当然是空的并且会中断您的查询。

我看到两个选项:

  • 用包含替换继承:

    public class StatsBySeason
    {
        public int Season { get; set; }
        public StatLines StatLines { get; set; }
    
        public string SeasonYears => Season + " / " + (Season + 1);
    }
    
  • 让 EF 使用 Fluent 配置忽略 StatsBySeason 类:

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

    或数据注释:

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

【讨论】:

  • 谢谢,我不知道 TPH 继承。你的解决方案有效,我会选择我认为的第一个:)
  • 明白了,明白了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-10
  • 1970-01-01
  • 2011-04-01
相关资源
最近更新 更多