MartenDB升级至5.11后Coalesce运算符及可空类型问题咨询
Marten 5.11升级后可空类型与Duplicate方法的问题解答
问题背景
环境:.NET7,将Marten从4版本升级至5.11后,执行以下代码触发异常:
storeOptions.Schema.For<UserSession>() .Identity(x => x.Key) .Duplicate(x => x.SessionId ?? "");
异常信息:
ERROR: System.ArgumentOutOfRangeException: Unsupported operator 'Coalesce' in a field member expression (Parameter 'node') at Marten.Linq.Parsing.FindMembers.VisitBinary(BinaryExpression node) at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node) at Marten.Schema.DocumentMapping`1.Duplicate(Expression`1 expression, String pgType, Nullable`1 dbType, Action`1 configure, Boolean notNull) at Marten.MartenRegistry.DocumentMappingExpression`1.<>c__DisplayClass6_0.<Duplicate>b__0(DocumentMapping`1 mapping) at Marten.DocumentMappingBuilder`1.Build(StoreOptions options) at Marten.Storage.StorageFeatures.Build(Type type, StoreOptions options) ...
若修改为以下代码,会触发可空类型错误(SessionId定义为public string? SessionId { get; set; }):
.Duplicate(x => x.SessionId);
使用以下代码可解决问题:
.Duplicate(x => x.SessionId!);
MartenDb的Duplicate方法签名:
public MartenRegistry.DocumentMappingExpression<T> Duplicate( Expression<Func<T, object>> expression, ...)
问题解答
1. 从报错信息来看,是否可空类型在此场景下不适用?
不是可空类型本身不适用,问题出在Marten的Duplicate方法不支持解析带合并运算符(??)的表达式。报错明确指出不支持Coalesce(合并)运算符,你用x.SessionId ?? ""这种包含二元运算的表达式时,Marten的表达式解析器无法处理。
而x.SessionId!能生效,是因为!是空值抑制运算符,它只是告诉编译器忽略可空警告,最终生成的表达式还是直接指向SessionId成员,没有额外的运算逻辑,Marten可以正常解析这种单纯的成员访问表达式。
2. C#中成员字段表达式与可空类型的相关规则是什么?能否构造不感知可空类型的成员字段表达式?
相关规则
- 当开启可空引用类型检查时,如果表达式返回可空引用类型(比如
string?),而方法参数要求非可空的object,编译器会触发可空警告/错误。因为string?装箱为object时会保留可空状态,编译器默认不允许这种隐式转换。 - 访问可空类型的成员时,编译器默认会生成带可空检查的表达式;如果使用
!运算符,则会生成直接的成员访问表达式,跳过编译器的可空检查。
构造不感知可空的成员表达式的方法
可以构造,核心是让表达式是单纯的成员访问,不带额外运算,同时让编译器接受可空类型到非可空参数的转换:
- 方法一:使用
!空值抑制运算符,如x => x.SessionId!。这种方式仅抑制编译器警告,运行时不改变原字段的可空性,Marten能正常解析。 - 方法二:显式转换为非可空类型,如
x => (string)x.SessionId。但这种方式如果SessionId为null,运行时会抛出NullReferenceException,不如!安全。 - 注意:绝对不能使用带运算逻辑的表达式(比如
??、?.等),因为Marten的Duplicate方法仅支持解析单纯的成员访问表达式,不支持二元运算或空传播运算。
内容的提问来源于stack exchange,提问作者Jevon Kendon
相关产品推荐
相关产品推荐

