Search code examples
c#sql-serverservicestackormlite-servicestack

ServiceStack OrmLite Multi Self References bug


I am trying to load references but in this case with two references from the same table it is not working

[Required]
public DateTime CreatedOn { get; set; }
public DateTime? ModifiedOn { get; set; }

[References(typeof(Employee))]
public int? CreatedById { get; set; }
[Reference]
public Employee CreatedBy { get; set; }

[References(typeof(Employee))]
public int? ModifiedById { get; set; }
[Reference]
public Employee ModifiedBy { get; set; }

As you can see above, I did it on the right way as the documentation of ORMLite: https://github.com/ServiceStack/ServiceStack.OrmLite

It is not loading the properties: ModifieldBy and CreatedBy even if the properties ModifiedById and CreatedById have values. I tried with required fields and it worked, but when I try with int? nulable it doesnt work.

You can see in the picture below that I have one record with the value "5" in the column ModifiedById so my Loadreferences of my method should get the column: ModifiedBy (with the Employee object loaded) it works in other cases, not in this case. enter image description here


Solution

  • I've added a passing test that tests multiple Self References with nullable int? Ids in this commit:

    Types Used:

    public class ParentSelfRef
    {
        [AutoIncrement]
        public int Id { get; set; }
    
        [References(typeof(ChildSelfRef))]
        public int? Child1Id { get; set; }
    
        [Reference]
        public ChildSelfRef Child1 { get; set; }
    
        [References(typeof(ChildSelfRef))]
        public int? Child2Id { get; set; }
    
        [Reference]
        public ChildSelfRef Child2 { get; set; }
    }
    
    public class ChildSelfRef
    {
        [AutoIncrement]
        public int Id { get; set; }
        public string Name { get; set; }
    }
    

    Drop and re-create tables:

    db.DropTable<ParentSelfRef>();
    db.DropTable<ChildSelfRef>();
    
    db.CreateTable<ChildSelfRef>();
    db.CreateTable<ParentSelfRef>();
    

    Create record with multiple self references:

    var row = new ParentSelfRef
    {
        Child1 = new ChildSelfRef
        {
            Name = "Child 1"
        },
        Child2 = new ChildSelfRef
        {
            Name = "Child 2"
        },
    };
    

    Save and test populated row:

    db.Save(row, references: true);
    
    row.PrintDump();
    
    Assert.That(row.Id, Is.EqualTo(1));
    Assert.That(row.Child1Id, Is.EqualTo(1));
    Assert.That(row.Child1.Id, Is.EqualTo(1));
    Assert.That(row.Child1.Name, Is.EqualTo("Child 1"));
    Assert.That(row.Child2Id, Is.EqualTo(2));
    Assert.That(row.Child2.Id, Is.EqualTo(2));
    Assert.That(row.Child2.Name, Is.EqualTo("Child 2"));
    

    Load row with self references:

    row = db.LoadSingleById<ParentSelfRef>(row.Id);
    
    Assert.That(row.Id, Is.EqualTo(1));
    Assert.That(row.Child1Id, Is.EqualTo(1));
    Assert.That(row.Child1.Id, Is.EqualTo(1));
    Assert.That(row.Child1.Name, Is.EqualTo("Child 1"));
    Assert.That(row.Child2Id, Is.EqualTo(2));
    Assert.That(row.Child2.Id, Is.EqualTo(2));
    Assert.That(row.Child2.Name, Is.EqualTo("Child 2"));