【问题标题】:Linq Entity Framework Ignoring IS NOT NULLLinq 实体框架忽略不为空
【发布时间】:2018-03-15 09:09:45
【问题描述】:

当我执行如下代码时,我有一个可以为空的列的表...

IList<IChecklistQuestionEntity> questions = repository.Where(q => q.OriginalQuestionID.HasValue);
IList<IChecklistQuestionEntity> originalQuestions = repository.Where(q => !q.OriginalQuestionID.HasValue);

...我在分析器中看到的是...

SELECT 
    [Extent1].[ID] AS [ID], 
    [Extent1].[OriginalQuestionID] AS [OriginalQuestionID], 
    [Extent1].[Question] AS [Question], 
    FROM [dbo].[cklChecklistQuestion] AS [Extent1]
    ORDER BY [Extent1].[Question] ASC

SELECT 
    CAST(NULL AS int) AS [C1], 
    CAST(NULL AS int) AS [C2], 
    CAST(NULL AS varchar(1)) AS [C3], 
    FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
    WHERE 1 = 0

EF类实现如下...

[Table("cklChecklistQuestion")]
public class ChecklistQuestionEntity 
{
    /// <summary>
    /// Gets or sets the ID
    /// </summary>
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID 
    { 
        get;
        set;
    }

    /// <summary>
    /// Gets or sets the OriginalQuestionID
    /// </summary>
    public int? OriginalQuestionID 
    { 
        get;
        set;
    }       

    [Required]
    public string Question 
    { 
        get;
        set;
    }

    public ICollection<ChecklistQuestionEntity> Revisions { get; set; }
}

当然,我希望在第一个查询中看到 Where IS NOT NULL 子句,在 where IS NULL 的表上看到第二个选择。

我在搜索中使用的是 EF 6.1.3,看来这个问题已经存在,但应该得到修复。 EF 6.2 在这个问题上会给我更多的乐趣吗?

编辑:我尝试过在 OriginalQuestionID 属性上使用和不使用虚拟关键字

EDIT2:我也尝试过不使用存储库而只使用 EF 上下文

IList<ChecklistQuestionEntity> questions = context.Set<ChecklistQuestionEntity>().Where(q => q.OriginalQuestionID.HasValue).ToList();
IList<ChecklistQuestionEntity> originalQuestions = context.Set<ChecklistQuestionEntity>().Where(q => !q.OriginalQuestionID.HasValue).ToList();

得到了同样的结果。

表的创建看起来像...

CREATE TABLE [dbo].[cklChecklistQuestion](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [OriginalQuestionID] [int] NULL,
    [Question] [nvarchar](450) NOT NULL,
 CONSTRAINT [PK_cklChecklistQuestion] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

ALTER TABLE [dbo].[cklChecklistQuestion]  WITH CHECK ADD  CONSTRAINT [FK_cklChecklistQuestion_cklChecklistQuestion] FOREIGN KEY([OriginalQuestionID])
REFERENCES [dbo].[cklChecklistQuestion] ([ID])
GO

ALTER TABLE [dbo].[cklChecklistQuestion] CHECK CONSTRAINT [FK_cklChecklistQuestion_cklChecklistQuestion]
GO

EDIT3:我认为这篇文章建议它应该被修复

How can i query for null values in entity framework?

EDIT4:也许它与这个问题有关...... Entity Framework Linq equals value or is null

虽然不同,但 OriginalQuestionID 不是主键的一部分,但它是同一张表上主键的外键关系

EDIT5:抱歉……当我试图在一个较小的应用程序中复制这个问题时,我发现我遗漏了一个关键部分。我已经修改了上面的代码以包含一个 Revisions 属性。另外,您需要以下上下文。

public class MyContext : DbContext
{
    public MyContext(string nameOrConnectionString) : base(nameOrConnectionString)
    {
    }

    protected MyContext()
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // Commenting out the following resolves the issue
        modelBuilder.Entity<ChecklistQuestionEntity>()
            .HasRequired(cq => cq.OriginalQuestion)
            .WithMany(cq => cq.Revisions)
            .HasForeignKey(cq => cq.OriginalQuestionID)
            .WillCascadeOnDelete(false);
    }
}

【问题讨论】:

  • 您确定这些查询与那些 EF LINQ 语句相关吗?
  • 请向我们展示 cklChecklistQuestion 的 CREATE TABLE 语句。
  • @mjwills 有很多类似的问题。这是让我认为这在 6.13 中不应该成为问题的原因。stackoverflow.com/questions/682429/…
  • 请使用该信息更新您的帖子。
  • @Mick 我相信链接的问题与在变量中使用空值有关,这导致 EF 在比较空值时使用非 ANSI 等于运算符。您的问题似乎完全不同。

标签: c# .net entity-framework-6


【解决方案1】:

好吧,这不是真正的解决方案,但问题是由添加了修订导航属性引起的。删除此语句即可解决问题。

modelBuilder.Entity<ChecklistQuestionEntity>()
        .HasRequired(cq => cq.OriginalQuestion)
        .WithMany(cq => cq.Revisions)
        .HasForeignKey(cq => cq.OriginalQuestionID)
        .WillCascadeOnDelete(false);

我认为这是一个错误,它与此处讨论的问题有关...

Entity Framework Linq equals value or is null

虽然 OriginalQuestionID 不是表上的键的一部分,但它与表的主键相关,这似乎导致 EF 不再相信它可以为空。

我尝试升级到 EF 6.2,但问题仍然存在。

我唯一的解决方法是删除 Revisions 导航属性。

【讨论】:

猜你喜欢
  • 2014-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-27
  • 1970-01-01
  • 1970-01-01
  • 2017-07-07
  • 1970-01-01
相关资源
最近更新 更多