Lets say I have these classes:
public class Foo
{
public IReadonlyDictionary<string, DateTime> Values { get; set; }
}
public class Bar
{
public Foo Foo { get; set; }
}
Now if I do this projection:
var projection = Builders<Bar>.Projection.Expression(x => x.Foo.Values["key"])
I will get DateTime.MinValue
and not a null in case the element key
does not exist in the dictionary. The value itself indeed cannot be null (and I assume that is why MongoDB is doing default(DateTime)
), but it can happen that it does not exist in the dictionary.
I am wondering if there is a good way to tell MongoDB that the result should be DateTime?
so that I can get a null in case the element does not exist.
P.S. I can make the dictionary value DateTime?
, and that will work but I would rather avoid it, since the Value
itself should not ever be null.
Sample documents:
// With values
{
"_t": "Bar",
"Foo":
{
"1521": "2022-09-26T08:25:38.502 00:00"
}
}
// Empty
{
"_t": "Bar",
"Foo":
{
}
}
CodePudding user response:
The following query returns the values as DateTime?
; if there is no Foo
, it is null, if it is set, it returns the value:
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();
For the following documents
{ "_id": { "$oid": "632dc047e08f08bfaeabc2d6" }, "Foo": null}
{ "_id": { "$oid": "632dc047e08f08bfaeabc2d7" }, "Foo": { "Value": { "$date": { "$numberLong": "1663942727428" } } }}
the result is
null
2022-09-23T14:18:47Z
Update: Dictionary
If you want to project the DateTime
from a Dictionary<string, DateTime>
, you can use the following expression with a ternary operator that checks against 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();
Based upon the sample documents (with the datetime changed to a Date data type in MongoDB), this finds the following data:
26.09.2022 08:25:38
null