C# ASP.NET MVC6“未定义二进制运算符Equal”

C# ASP.NET MVC6“未定义二进制运算符Equal”,c#,asp.net,entity-framework,entity-framework-core,C#,Asp.net,Entity Framework,Entity Framework Core,我有这个模型: [Table("tblDbFile")] public class DbFile { [Key] public Guid Id { get; set; } public string Name { get; set; } public string Engine { get; set; } public string Hash { get; set; } public long Size { get; set; } publ

我有这个模型:

[Table("tblDbFile")]
public class DbFile
{
    [Key]
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Engine { get; set; }
    public string Hash { get; set; }
    public long Size { get; set; }
    public DbDir Directory { get; set; }
}

[Table("tblDbDir")]
public class DbDir
{
    [Key]
    public Guid Id { get; set; }
    public string Name { get; set; }
    public DbDir Parent { get; set; }
}
如果我尝试执行行_context.DbFile.Wheren=>n.Directory==Dir,则会出现以下错误:

Dir是DbDir类型

信息:

InvalidOperationException:未为类型“System.Nullable`1[System.Guid]”和“Models.DbDir”定义二进制运算符Equal

我如何解决这个问题?使用_context.DbFile.Wheren=>n.Directory.Id==Dir.Id可以工作,但这不是我的选项,因为首先,我必须大量使用这些类型的引用,其次,Dir可以为null

我已经试过了:

重写==和!=对象的运算符,这确实有效,但它不再优化SQL查询,而是在C中进行比较。 试图将Dir声明为DbDir?失败 使用n.Directory.EqualsDir与重写时存在相同的问题== 在表达式中使用Dir???.Id失败
正如您所发现的,查询生成器无法转换运算符。您必须使用您不喜欢的版本:

_context.DbFile.Where(n => n.Directory.Id == Dir.Id)
是的,这在空的情况下是有问题的;所以在这种情况下,您需要以不同的方式编写:

if(Dir == null) {
    query = _context.DbFile.Where(n => n.Directory == null);
}
else {
    query = _context.DbFile.Where(n => n.Directory.Id == Dir.Id);
}
作为旁白;如果您也有n.DirectoryId,您可能会发现使用它很方便:

if(Dir == null) {
    query = _context.DbFile.Where(n => n.DirectoryId == null);
}
else {
    var id = Dir.Id;
    query = _context.DbFile.Where(n => n.DirectoryId == id);
}
通过检查Dir是否为null,可以很容易地解决Dir为null的问题,只有当Dir不为null时,才能比较id,如下所示:

_context.DbFile.Where(n => Dir == null || n.Directory.Id == Dir.Id)
或者,如果n.Directory也可以为null,并且应该与Dir==null匹配,则使用以下方法:

_context.DbFile.Where(n => (Dir == null && n.Directory == null)
                        || (Dir != null && n.Directory.Id == Dir.Id))

注意:对于这种类型的复杂性,您需要谨慎一点——它会很快导致生成的查询非常次优。很明显,这在很大程度上取决于所使用的工具——我想说的是:确保查看生成的工具。@MarcGravel我刚刚检查过。查询是N'N'N'N'N'N'N'N'N'N'N'N'N'N'N'N'N'N'N'N[N][N][N][N][[N][[N][[N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N][N 0,@u p_1=1,@__目录Id_2='3D4AF7D3-18CE-48F0-1E75-08D4298C31D6'。当然更复杂,但仍然使用SQL进行比较,而不是C@AyrA是的,那是一种会让我彻夜不眠的东西;我对我的SQL非常挑剔:这是哪个版本的EF Core?旧版本中存在的问题可能导致此异常消息已经修复,但其他问题可能仍然存在。这个特殊的异常消息清楚地指出了EF中的一个bug:它抱怨您没有执行的特定比较。EF的异常消息应该说您正在做的事情不受支持,或者应该进行适当的翻译。如果它仍然存在于最新版本中,并且还未知,则可能值得在他们的问题跟踪器上报告。@hvd 7.0.0-rc1-163487.0.*是旧版本号,此版本号在rc1之后被删除。当前版本为1.1.0。看见它在NuGet上也可用,而不是。这在null情况下是有问题的-为什么?表达式不仅仅是被检查的,而不是被执行的吗?查询生成器没有办法翻译操作符——它当然有办法。它可能没有实现,也可能实现不正确,但这不是不可能的,异常消息向我表明EF正在尝试实现它。@CodeCaster确实,它是一个被拆开的表达式树-但是:这并不意味着每个引擎都能理解每种可能的设置。事实上,null成员的值往往没有很好的支持,因此是有问题的。尽管公平地说,还不清楚对某件事情是否有一个有效的解释,如果执行该解释,就会引发一个例外。@Marc无视我之前的评论,我不应该在现有答案下提出新问题。无论如何,谢谢你的解释。