MongoDB 未拾取 C# 相等覆盖
MongoDB C# Equality override isn't picked up
我有以下代码块:
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 的自定义 class 中的 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()。
无法实现此行为,这是因为驱动程序仅 "knows" 某些类型的方法并且能够将它们转换为 MongoDB 查询。
想象一下,您在自定义 Equals
实现中编写了各种时髦的代码(例如调用网络服务或记录一些内容或其他内容)。驱动程序会怎么做才能将其转换为 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;
}
我有以下代码块:
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 的自定义 class 中的 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()。
无法实现此行为,这是因为驱动程序仅 "knows" 某些类型的方法并且能够将它们转换为 MongoDB 查询。
想象一下,您在自定义 Equals
实现中编写了各种时髦的代码(例如调用网络服务或记录一些内容或其他内容)。驱动程序会怎么做才能将其转换为 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;
}