首页 > 解决方案 > MongoDB C# Equality override 没有被选中

问题描述

我有以下代码块:

    public bool Equals(TranslatedTextReference other)
    {
        if (other is null) return false;
        return Translations.Equals(other.Translations);
    }

    public bool Equals(string other)
    {
        foreach(KeyValuePair<string, string> pair in Translations)
        {
            if (other.Equals(pair.Value, StringComparison.InvariantCultureIgnoreCase))
                return true;
        }
        return false;
    }

    public static bool operator ==(TranslatedTextReference left, TranslatedTextReference right) => left.Equals(right);
    public static bool operator !=(TranslatedTextReference left, TranslatedTextReference right) => left.Equals(right);

    public static bool operator ==(TranslatedTextReference left, string right) => left.Equals(right);
    public static bool operator !=(TranslatedTextReference left, string right) => !left.Equals(right);

它覆盖了名为 TranslatedTextReference 的自定义类中的 Equlas 和 == 行为。和

database.GetCollection<Element>("elements").AsQueryable()
            .FirstOrDefault(element => element.TranslatedElementName == name);

理论上应该查询 Mongo 并使用覆盖的 == 运算符。实际上,这不起作用,因为(我假设)实际上并未调用被覆盖的运算符,因为 LINQ 查询是直接在 MongoDB 服务器上作为 MongoDB 查询执行的。事实上,使用默认相等运算符的另一段代码可以完美运行。

database.GetCollection<Element>("elements").AsQueryable()
            .FirstOrDefault(element => element.AtomicNumber == atomicNumber);

AtomicNumber 是一个整数。

有没有办法让 MongoDB 使用我的自定义运算符?

另外,我知道我可以只使用默认运算符并使用它们构建相同的查询,但我必须在我的 LINQ 查询中使用 == 或 .Equals()。

标签: c#mongodblinqoperator-overloadingequality

解决方案


没有办法实现这种行为,这是因为驱动程序只“知道”某些类型的方法并且能够将它们转换为 MongoDB 查询。

想象一下,您在自定义实现中编写了各种时髦的代码Equals(例如调用 Web 服务或记录一些内容或其他内容)。驱动程序会做什么才能将其转换为 MongoDB 查询?

当您查看驱动程序代码时,您会发现翻译逻辑只是基于您作为谓词传递的表达式树中相应方法的名称:

private FilterDefinition<BsonDocument> TranslateMethodCall(MethodCallExpression methodCallExpression)
{
    switch (methodCallExpression.Method.Name)
    {
        case "Contains": return TranslateContains(methodCallExpression);
        case "ContainsKey": return TranslateContainsKey(methodCallExpression);
        case "EndsWith": return TranslateStringQuery(methodCallExpression);
        case "Equals": return TranslateEquals(methodCallExpression);
        case "HasFlag": return TranslateHasFlag(methodCallExpression);
        case "In": return TranslateIn(methodCallExpression);
        case "IsMatch": return TranslateIsMatch(methodCallExpression);
        case "IsNullOrEmpty": return TranslateIsNullOrEmpty(methodCallExpression);
        case "StartsWith": return TranslateStringQuery(methodCallExpression);
    }

    return null;
}

推荐阅读