未使用MongoDB C#平等替代

时间:2018-10-24 19:07:54

标签: c# mongodb linq operator-overloading equality

我有以下代码块:

    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()。

1 个答案:

答案 0 :(得分:2)

由于驱动程序仅“知道”某些类型的方法并将其转换为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;
}