linq 有没有办法用表达式和字典从MongoDB C#驱动程序投影中获取一个可空值?

00jrzges  于 2022-12-06  发布在  Go
关注(0)|答案(1)|浏览(135)

假设我有这些类:

public class Foo
{
   public IReadonlyDictionary<string, DateTime> Values { get; set; }
}

public class Bar
{
   public Foo Foo { get; set; }
}

现在如果我做这个投影:

var projection = Builders<Bar>.Projection.Expression(x => x.Foo.Values["key"])

如果字典中不存在key元素,我将得到DateTime.MinValue,而不是null。值本身确实不能为null(我假设这就是MongoDB执行default(DateTime)的原因),但它可能不存在于字典中。
我想知道是否有一个好的方法告诉MongoDB结果应该是DateTime?,这样我就可以在元素不存在的情况下得到一个空值。
另外,我可以将字典值设为DateTime?,这也可以,但我宁愿避免它,因为Value本身不应该为空。
示例文档:

// With values
{
  "_t": "Bar",
  "Foo":
    {
      "1521": "2022-09-26T08:25:38.502+00:00"
    }
}

// Empty
{
  "_t": "Bar",
  "Foo":
    {
    }
}
yc0p9oo0

yc0p9oo01#

以下查询返回DateTime?形式的值;如果没有Foo,则为null,如果设置了,则返回值:

var bars = await (await barColl.FindAsync(
  Builders<Bar>.Filter.Empty, 
  new FindOptions<Bar, DateTime?>()
  {
    Projection = Builders<Bar>.Projection.Expression(
      x => (DateTime?) (x.Foo == null ? null : x.Foo.Value))
  })).ToListAsync();

对于以下文档

{ "_id": { "$oid": "632dc047e08f08bfaeabc2d6" }, "Foo": null}
{ "_id": { "$oid": "632dc047e08f08bfaeabc2d7" }, "Foo": { "Value": { "$date": {  "$numberLong": "1663942727428" } } }}

结果是

null
2022-09-23T14:18:47Z

更新:字典

如果您要从Dictionary<string, DateTime>投影DateTime,可以使用下列运算式搭配三元运算子来检查default(DateTime)

var projection = Builders<SoNullableDt>.Projection
  .Expression<DateTime?>(
    x => x.Foo["1521"] == default(DateTime) ? null : x.Foo["1521"]);
var result = await (await coll.FindAsync(Builders<SoNullableDt>.Filter.Empty, 
  new FindOptions<SoNullableDt, DateTime?>() { Projection = p })).ToListAsync();

根据示例文档(在MongoDB中将datetime更改为Date数据类型),可以找到以下数据:

26.09.2022 08:25:38
null

相关问题