litedb-org/LiteDB · error · NotSupportedException

BsonRefId<T> requires a DbRef collection name. Member '{memb

Error message

BsonRefId<T> requires a DbRef collection name. Member '{memberMapper.MemberName}' is missing it (use [BsonRef] or Entity<T>().DbRef(...)).

What it means

Thrown when a LINQ expression assigns a BsonRefId<T> to a property that is registered as a DbRef but whose target collection name is null or empty. LiteDB needs the collection name to emit the {$id, $ref} reference document, so it refuses to translate the expression without one. The DbRefCollectionName is normally populated by [BsonRef("collection")] or Entity<T>().DbRef(x => x.Prop, "collection").

Source

Thrown at LiteDB/Client/Mapper/Linq/LinqExpressionVisitor.cs:755

            }

            return value;
        }

        /// <summary>
        /// Tries to visit `new BsonRefId&lt;T&gt;(id)` within a member init expression.
        /// This is only resolved for properties marked as DbRef.
        /// </summary>
        private bool TryVisitDbRefIdExpression(Expression node, MemberMapper memberMapper, bool isInList = false)
        {
            if (!memberMapper.IsDbRef)
            {
                return false;
            }

            if (string.IsNullOrWhiteSpace(memberMapper.DbRefCollectionName))
            {
                throw new NotSupportedException($"BsonRefId<T> requires a DbRef collection name. Member '{memberMapper.MemberName}' is missing it (use [BsonRef] or Entity<T>().DbRef(...)).");
            }

            switch (node)
            {
                // Implicit convert from BsonRefId<T> to T
                case UnaryExpression { NodeType: ExpressionType.Convert, Method: { Name: "op_Implicit" }, Operand: var operand }:
                    return TryVisitDbRefIdExpression(operand, memberMapper, isInList);

                // The actual new BsonRefId<T>
                case NewExpression { Members: null, Type.IsConstructedGenericType: true } expr
                    when expr.Type.GetGenericTypeDefinition() == typeof(BsonRefId<>):

                    var typeOfRef = expr.Type.GetGenericArguments()[0];

                    // Type of ref must be assignable to property or if within a list assignable to the list type.
                    if (memberMapper.DataType.IsAssignableFrom(typeOfRef) || isInList && memberMapper.UnderlyingType.IsAssignableFrom(typeOfRef))
                    {
                        ResolveDbRefId(expr, memberMapper);

View on GitHub (pinned to f906a5f850)

Solutions

  1. Add an explicit collection name to the attribute: [BsonRef("myCollection")] on the property.
  2. Use the fluent API with a name: db.Mapper.Entity<T>().DbRef(x => x.Prop, "myCollection").
  3. Ensure the referenced type's default collection name (type name lowercased) matches an actual collection in the database.

Example fix

// before
public class Order
{
    [BsonRef]
    public Customer Customer { get; set; }
}
// after
public class Order
{
    [BsonRef("customers")]
    public Customer Customer { get; set; }
}
Defensive patterns

Strategy: validation

Validate before calling

// Before building LINQ update expressions, verify DbRef members have a collection name
var mapper = db.Mapper;
var entity = mapper.GetEntityMapper<Order>();
foreach (var member in entity.Members.Where(m => m.IsDbRef))
{
    if (string.IsNullOrWhiteSpace(member.DbRefCollectionName))
        throw new InvalidOperationException(
            $"Member {member.MemberName} is a DbRef without a collection name. Add [BsonRef(\"name\")] or Entity<T>().DbRef(..., \"name\").");
}

Try / catch

try
{
    col.UpdateMany(x => new Order { Customer = new BsonRefId<Customer>(id) }, x => x.Id == orderId);
}
catch (NotSupportedException ex) when (ex.Message.Contains("DbRef collection name"))
{
    // Fix the mapping: add [BsonRef("customers")] to the property
    throw;
}

Prevention

When it happens

Trigger: A DbRef member was declared with [BsonRef] (parameterless) or via DbRef(...) without a collection argument, and the mapper could not infer the name from the type. A LINQ update/insert expression then uses new BsonRefId<T>(id) on that member, entering TryVisitDbRefIdExpression where IsDbRef is true but DbRefCollectionName is blank.

Common situations: Using the parameterless [BsonRef] attribute and expecting auto-inference from the type name when it doesn't match the convention. Migrating from an older LiteDB version where collection names were optional. Using a fluent mapper Entity<T>().DbRef(x => x.Prop) without the second string argument.

Related errors


AI-assisted analysis of litedb-org/LiteDB@f906a5f850 (2026-08-13). Data as JSON: /api/errors/6d99acbf2eb0ff14. Report an issue: GitHub.