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

时间:2016-12-21 12:31:04

标签: 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; }
    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.Where(n => n.Directory == Dir)行,我会收到此错误:

Dir的类型为DbDir)

消息:

  

InvalidOperationException:没有为类型'System.Nullable`1 [System.Guid]'和'Models.DbDir'定义二元运算符Equal。

我该如何解决这个问题?使用_context.DbFile.Where(n => n.Directory.Id == Dir.Id)有效,但这对我来说不是一个选项,因为首先,我必须使用这些类型的引用,其次,Dir可以为null。

我已经尝试过:

  • 覆盖对象的==!=运算符,这些运算符确实有效,但它不再优化SQL查询,而是在C#中进行比较。
  • 尝试将Dir声明为DbDir?(失败)
  • 使用n.Directory.Equals(Dir)(与覆盖==相同的问题)
  • 在表达式中使用Dir??.Id(失败)

2 个答案:

答案 0 :(得分:2)

如您所见,查询生成器无法翻译您的运算符。您 使用您不喜欢的版本:

_context.DbFile.Where(n => n.Directory.Id == Dir.Id)

是的,这在null案件中存在问题;所以...在这种情况下,你需要以不同的方式写出来:

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);
}

答案 1 :(得分:1)

Dir为null的问题可以通过检查它是否为空来轻松解决,只有当它不为null时才比较Ids,如下所示:

_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))