【发布时间】:2020-05-03 14:19:09
【问题描述】:
我正在编写一个服务来处理游戏的禁令,我目前在尝试编写 MongoDB 查询时有点卡住了。目前我有一个“用户”对象的集合,这些对象看起来像这样:
public class User
{
public List<Ban> Bans { get; set; }
// some irrelevant additional fields
}
public class Ban
{
public HardwareId HWID { get; set; }
public DateTime Expires { get; set; }
// some irrelevant additional fields
}
public class HardwareId : IEquatable<HardwareId>
{
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }
public string Field4 { get; set; }
public bool Equals([AllowNull] HardwareId other)
{
if (ReferenceEquals(other, null)) return false;
if (ReferenceEquals(this, other)) return true;
return Field1 == other.Field1 &&
Field2 == other.Field2 &&
Field3 == other.Field3 &&
Field4 == other.Field4;
}
}
我想要做的是有一个查询来查找所有被禁止的用户,其中 HWID 说 4 个字段中的 3 个匹配。目前我有一个查询,只能找到 HWID 完全匹配的用户(由于 Equals() 实现),但我想更改它。我当前的代码如下所示:
public Ban FindBan(HardwareId hwid)
{
var banBuilder = Builders<Ban>.Filter;
var hwidFilter = banBuilder.Eq(b => b.HWID, hwid);
var expFilter = banBuilder.Gt(b => b.Expires, DateTime.UtcNow);
var banFilter = banBuilder.And(hwidFilter, expFilter);
var user = _users.Find(Builders<User>.Filter.ElemMatch(p => p.Bans, banFilter)).FirstOrDefault();
if (user != null)
{
return user.Bans[0];
}
return null;
}
我能想到的唯一解决方法是在 Equals() 函数中编写“意大利面条式 if 语句”,但我想要一个动态解决方案,以后可以在 HardwareId 类中添加多个“字段”下线。 FindBan() 函数目前的另一个问题是它返回“user.Bans[0]”而不是找到的实际禁令,但我想我可以通过按到期排序来解决这个问题。
【问题讨论】: