AutoQuery.Execute causing delegate null

I upgraded from ServiceStack 6.0.1 to the latest 6.3.1.

I now have a System.ArgumentException: Delegate to an instance method cannot have null ‘this’

It is being caused by my previously working 6.0.1 code:

//InvoiceService.cs

using var db = AutoQuery!.GetDb<Invoice>(Request);
var query = new ReadInvoice { InvoiceNumber = invoice.InvoiceNumber };
var q = AutoQuery.CreateQuery(query, Request, db);
var finds = AutoQuery.Execute(query, q, Request, db);   // error caused here on line 112

Stepping through the stack trace, it seems that the problem is that refModelDef is null in this method:

//ServiceStack.OrmLite.OrmLiteReadCommandExtensions.cs
public static FieldDefinition GetSelfRefFieldDefIfExists(this ModelDefinition modelDef, ModelDefinition refModelDef, FieldDefinition fieldDef)
{
    var refField = (fieldDef == null ? null
         : modelDef.FieldDefinitions.FirstOrDefault(x => x.ForeignKey != null && x.ForeignKey.ReferenceType == refModelDef.ModelType
             && fieldDef.IsSelfRefField(x)))
        ?? modelDef.FieldDefinitions.FirstOrDefault(x => x.ForeignKey != null && x.ForeignKey.ReferenceType == refModelDef.ModelType)
        ?? modelDef.FieldDefinitions.FirstOrDefault(refModelDef.IsRefField);

    return refField;
}

The stack trace was:

System.ArgumentException: Delegate to an instance method cannot have null 'this'.
 ---> System.ArgumentException: Delegate to an instance method cannot have null 'this'.
   at System.MulticastDelegate.ThrowNullThisInDelegateToInstance()
   at System.MulticastDelegate.CtorClosed(Object target, IntPtr methodPtr)
   at ServiceStack.OrmLite.OrmLiteReadCommandExtensions.GetSelfRefFieldDefIfExists(ModelDefinition modelDef, ModelDefinition refModelDef, FieldDefinition fieldDef) in 
   /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite/OrmLiteReadCommandExtensions.cs:line 1030
   at ServiceStack.OrmLite.Support.LoadListSync`2.SetRefField(FieldDefinition fieldDef, Type refType) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite/Support/LoadList.cs:line 257
   at ServiceStack.OrmLite.OrmLiteReadCommandExtensions.LoadListWithReferences[Into,From](IDbCommand dbCmd, SqlExpression`1 expr, IEnumerable`1 include) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite/OrmLiteReadCommandExtensions.cs:line 1002
   at ServiceStack.OrmLite.ReadExpressionCommandExtensions.LoadSelect[Into,From](IDbCommand dbCmd, SqlExpression`1 expression, IEnumerable`1 include) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite/Expressions/ReadExpressionCommandExtensions.cs:line 237
   at ServiceStack.OrmLite.OrmLiteReadExpressionsApi.<>c__DisplayClass65_0`2.<LoadSelect>b__0(IDbCommand dbCmd) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite/OrmLiteReadExpressionsApi.cs:line 435
   at ServiceStack.OrmLite.OrmLiteExecFilter.Exec[T](IDbConnection dbConn, Func`2 filter) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite/OrmLiteExecFilter.cs:line 66
   at ServiceStack.OrmLite.OrmLiteReadExpressionsApi.Exec[T](IDbConnection dbConn, Func`2 filter) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite/OrmLiteReadExpressionsApi.cs:line 18
   at ServiceStack.OrmLite.OrmLiteReadExpressionsApi.LoadSelect[Into,From](IDbConnection dbConn, SqlExpression`1 expression, IEnumerable`1 include) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.OrmLite/src/ServiceStack.OrmLite/OrmLiteReadExpressionsApi.cs:line 435
   at ServiceStack.TypedQuery`2.Execute[Into](IDbConnection db, ISqlExpression query) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Server/AutoQueryFeature.cs:line 1699
   --- End of inner exception stack trace ---
   at ServiceStack.TypedQuery`2.Execute[Into](IDbConnection db, ISqlExpression query) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Server/AutoQueryFeature.cs:line 1709
   at ServiceStack.AutoQuery.Execute[From](IQueryDb`1 model, SqlExpression`1 query, IRequest req, IDbConnection db) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Server/AutoQueryFeature.cs:line 1031
   at ServiceInterface.InvoiceNs.InvoiceService.GetNewInvoices(List`1 values) in C:\Tmp\ServiceInterface\InvoiceNs\InvoiceService.cs:line 112

Do I need to adjust my code elsewhere for 6.3.1?

What is refType at:

Can you also provide the Reference field properties in the Invoice class.

fieldDef: InvoiceTypeId refType: System.Guid

Invoice class:

using ServiceStack.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using LIB.DatabaseNs;

namespace ServiceType.InvoiceNs;

[Schema("Invoice")]
[DataContract]
public record Invoice : AuditBase
{
    [AutoId]
    [DataMember, Required]
    public Guid Id { get; init; }

    [DataMember, Required]
    public int ExtInvoiceId { get; init; }

    [DataMember]
    public int? EXtExecutionId { get; init; }

    [Reference]
    [DataMember, Required]
    public Guid InvoiceTypeId { get; init; }

    [DataMember, Required]
    public bool MaterialInvoice { get; init; }

    [DataMember, Required]
    public bool ProvisionalInvoice { get; init; }

    [DataMember, Required]
    public bool Revenue { get; init; }

    [DataMember, Required]
    public string InvoiceNumber { get; init; } = null!;

    [DataMember, Required]
    public string InvoiceShortCode { get; init; } = null!;

    [DataMember]
    public string? ExecutionNumber { get; init; }

    [DataMember, Required]
    public string CompanyCode { get; init; } = null!;

    [DataMember, Required]
    public string CounterpartyCode { get; init; } = null!;

    [DataMember, Required]
    public DateOnly InvoiceDate { get; init; }

    [DataMember, Required]
    public DateOnly ValueDate { get; init; }

    [DataMember, Required]
    public string CcyAlphaCode { get; init; } = null!;

    [DataMember, Required]
    public decimal FullAmountCcy { get; init; }

    [DataMember, Required]
    public decimal PayableAmountCcy { get; init; }

    [DataMember]
    public string? ExternalReference { get; init; }

    [Reference]
    [DataMember, Required]
    public List<InvoiceItem> InvoiceItem { get; init; } = new();

    [IgnoreOnInsert]
    [DataMember, Required]
    public bool Closed { get; init; }

    [Alias("DataEventRv")]
    [DataMember, Required]
    public ulong RowVersion { get; init; }
}

Hi Keith,

The [Reference] attribute needs to be on the Complex Type that the reference data is populated with, see POCO Reference docs for examples.

If you wanted to create a foreign Key instead you would use the [ForeignKey] or [References(Type)] attributes.

Thanks for helping, but is that not already the case above?

[Reference]
[DataMember, Required]
public Guid InvoiceTypeId { get; init; }

And this invoice class was working under 6.0, hence my confusion.

Guid is not a complex type, what is it, a normal column on the Invoice table, a foreign key?

Simplified DB table:

CREATE TABLE Invoice.Invoice (

    -- referential
    Id                                              UNIQUEIDENTIFIER DEFAULT NEWSEQUENTIALID(),
    IndexId                                         INT IDENTITY(1,1),

    -- entity columns WITH constraints
    ExtInvoiceId                  INT               NOT NULL,
    ExtExecutionId                INT               NULL, -- check constraint for not null when material invoice
    InvoiceTypeId                 UNIQUEIDENTIFIER  NOT NULL

    -- referential constraints
    CONSTRAINT invoice_invoice_pk PRIMARY KEY NONCLUSTERED (Id),
    CONSTRAINT invoice_invoice_invoicetype_fk FOREIGN KEY (InvoiceTypeId) REFERENCES Invoice.InvoiceType(Id),

So it’s just a column on the Invoice table, then it shouldn’t have the [Reference] attribute which defines an external complex type reference populated with OrmLite’s Load* APIs which AutoQuery uses to populate reference data.

Excellent, no idea what I was thinking; removing the [Reference] from InvoiceTypeId solved it.

I do not do that anywhere else, so looks like a stupid copy-paste error by me.

Thank you very much, mythz.

1 Like