Relation coming back from the database with different results for refrence id and for entity

Hi,
On the same entity I have the following structure:

 [References(typeof(NameEntity))]
 public long? PrimaryNameId { get; set; }
 [Reference]
 public NameEntity PrimaryName { get; set; }

 [Reference]
 public List<NameEntity> Names { get; set; } = new List<NameEntity>();

When I loadSelect by Id, I get different results for PrimaryName.Id and for PrimaryNameId

The correct value in the database is PrimaryNameId which is 4

What can that be?
Thanks

Not sure, is it affected by other NameEntity references you have on the same model? Seems you’re using a model with an FK as well to support your 1:M references, maybe that’s confusing it. I’m assuming Id is the PK?

Can you provide a stand-alone repo?

Hey
I think now you have all the information:

    public class BaseEntity
    {
        [AutoIncrement]
        [PrimaryKey]
        public long Id { get; set; }
        public DateTime CreatedAt { get; set; }
        public DateTime UpdatedAt { get; set; }
        public bool Deleted { get; set; } = false;
    }


  public class ResearchEntity : BaseEntity, IHasUserAudit
  {
        [References(typeof(NameEntity))]
        public long? PrimaryNameId { get; set; }
        [Reference]
        public NameEntity PrimaryName { get; set; }

        [Reference]
        public List<NameEntity> Names { get; set; } = new List<NameEntity>();
  }
   

public class NameEntity : BaseEntity,
    {
        
        public string Value { get; set; }
        [JsonConverter(typeof(StringEnumConverter))]
        public FindingStatus FindingStatus { get; set; } = FindingStatus.ACQUIRED;
        public virtual Source Source { get; set; }
        [References(typeof(ResearchEntity))]
        public long ResearchId { get ; set ; }
        [Reference]
        public ResearchEntity Research { get; set; }
        public DateTime? ScanningTime { get; set; }
        public BaseStringEntity(Source? source = null, string value = "")
        { 
            if (source != null)
            {
                this.Source = source.Value;
            }
            this.Value = value;
        }
    } 

   [JsonConverter(typeof(JsonStringEnumConverter))]
   public enum FindingStatus
   {
      ACQUIRED, PENDING
   }

   [JsonConverter(typeof(JsonStringEnumConverter))]
   public enum Source 
   {
       GOOGLE,BING  
   }

I need something I can run to repro it, please either provide a C# code snippet I can run (like a unit test) or create a runnable example on Gistlyn. that I can run that reproduces the issue.

A working test:

Please note. I dont know if this problem is with 5.8 or 5.8.1
I did not really managed to reproduce it with this test. I guess I need complexity in the data for that to be hapening.
When I looked yesterday on the running queries, somehting was odd.
The system did not run a speciphc query to bring PrimaryName, I guess its something internaly (or not).
Thanks

The foreign key is already populated by your first save with references. When you save it again you’ll need to update the FK, not the reference entity, e.g:

research.PrimaryNameId = research.Names[1].Id;
db.Save(research);

But this is not the problem.
In the database the correct value 4, When I loadSelect by Id, I get different results for PrimaryName.Id and for PrimaryNameId. Regardless of the saving action.

PrimaryName.Id = X
PrimaryNameId = Y

In order to solve this I’m doing:

res.PrimaryName = res.Names.Where(x => x.Id == res.PrimaryNameId).FirstOrDefault();

but this solution works only if PrimaryName is in the result of Names list.

Then what’s the repro? I’ve added a 4th NameEntity and updated PrimaryNameId to use it, e.g:

var research = new ResearchEntity();
research.Names.Add(new NameEntity { Value = "test 1" });
research.Names.Add(new NameEntity { Value = "test 2" });
research.Names.Add(new NameEntity { Value = "test 3" });

db.Save(research, references:true);
var newId = db.Insert(new NameEntity { Value = "test 4" }, selectIdentity:true);
research.PrimaryNameId = newId;
db.Save(research);

var res = db.LoadSelect(db.From<ResearchEntity>().Where(x => x.Id == 1));
res.PrintDump();

Which prints out the expected populated POCO:

[
	{
		PrimaryNameId: 4,
		PrimaryName: 
		{
			Value: test 4,
			ResearchId: 0,
			Id: 4
		},
		Names: 
		[
			{
				Value: test 1,
				ResearchId: 1,
				Id: 1
			},
			{
				Value: test 2,
				ResearchId: 1,
				Id: 2
			},
			{
				Value: test 3,
				ResearchId: 1,
				Id: 3
			}
		],
		Id: 1
	}
]

Please provide the code that repro’s the behavior you’re describing.

The problem is definetly comming from the new version in MyGet. I rolled back to and the problem disapear. then I update back and the problem is there again.
I can’t repreduce it in a somple test.
Is there any chance you have 5 minutes for teamviewer/anydesk to my pc just for you to see this…
Im kind of stuck in the middle, I cant go back and I cant really roll out an update to production.
I would really appereceate your flexability here. its a major thing.
Thanks

No I definitely need a stand-alone repro to be able to identify & resolve it, if it can’t be resolved within a code sample following your assumptions & description then you most likely have other environmental factors impacting it that’s not being considered or included, i.e. why a stand-alone repro is paramount as it tests your assumptions & forces you to include all environmental factors causing it into the repro. A report isn’t useful without one.

Have a look at the generated SQL if it’s not generating the expected SQL then either the behavior or your assumptions are incorrect.

Enable strict mode if you haven’t already and debug logging if you haven’t already in-case that any more insights:

LogManager.LogFactory = new ConsoleLogFactory();
//...
Env.ScriptMode = true;

Then like identifying any issue, you need to isolate it as much as possible until you’re able to identify it, e.g. disable/remove all other code & services from running except the isolated code that has the issue.

Reproducable test: https://gist.github.com/avifatal/06190e3cd12c262f660d0a75a497e114

Yeah the different types of references for the same type in the same model was the issue which was solved in the sync API version, but not in the async which should be resolved from this commit. I’m assuming it worked before was because you were using the sync version as that class hadn’t been touched for a long time. This change is available from the latest v5.8.1 that’s now available on MyGet (where you’ll need to clear your existing NuGet packages cache).

Note you still need to update your FK’s with:

research.PrimaryNameId = research.Names[1].Id;
await db.SaveAsync(research);

Having cyclical FK references like this is likely to cause a world of pain in future, as evident by needing to disable FK checks when creating the table schemas since it’s not possible to order the drop/create tables in a way to avoid violating the constraints. It’s a code-smell that which I’d avoid by ensuring only one-way references.

If I was to model this table I’d only have the 1:M Reference and a flag to indicate which one is the primary record which should make it much simpler to maintain (+ reduced db hits) & you can still have your PrimaryName getter for easy access, e.g:

public class ResearchEntity : BaseEntity
{
    public NameEntity PrimaryName => Names.FirstOrDefault(x => x.IsPrimary);

    [Reference]
    public List<NameEntity> Names { get; set; } = new List<NameEntity>();
}

How do I reset the production nuget? like the link you provided. I’m using docker.
Thanks

You shouldn’t need to clear the cache as it shouldn’t be caching the NuGet packages & would be fetching the latest packages each time.