question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

LinqToDb fails with "Association key not found for type"

See original GitHub issue

Trying to use linq2db with existing EF code base and found a case, which might be interesting to you as it seems to be valid for EF, but will fail in runtime when linq2db is used as expression engine.

Let’s say we have next domain model:

public class Container
{
	public int Id { get; set; }
	public virtual ICollection<Item> Items { get; set; }
	public virtual ICollection<ChildItem> ChildItems { get; set; }
}

public class Item
{
	public int Id { get; set; }
	public int ContainerId { get; set; }
	public virtual ChildItem Child { get; set; }
	public virtual Container Container { get; set; }
}

public class ChildItem
{
	public int Id { get; set; }
	public virtual Item Parent { get; set; }
}

ChildItem here is basically a descendant of Item, but relationship is implemented with use of composition instead of inheritance (migrating from EF 6 to EF Core 3, which doesn’t support Table Per Type for hierarchies, hence such design). And of course in real-world model both Item and ChildItem have more attributes and there’re multiple Item “descendants” omitted here for brevity.

Configuration for these entities is as follows:

internal sealed class ContainerConfiguration : IEntityTypeConfiguration<Container>
{
	public void Configure(EntityTypeBuilder<Container> _)
	{
		_.HasKey(x => x.Id);
		_.Property(x => x.Id).UseIdentityColumn();
	}
}

internal sealed class ItemConfiguration : IEntityTypeConfiguration<Item>
{
	public void Configure(EntityTypeBuilder<Item> _)
	{
		_.HasKey(x => x.Id);
		_.Property(x => x.Id).UseIdentityColumn();

		_.HasOne(a => a.Container)
			.WithMany(b => b.Items)
			.IsRequired()
			.HasForeignKey(a => a.ContainerId);
	}
}

internal sealed class ChildItemConfiguration : IEntityTypeConfiguration<ChildItem>
{
	public void Configure(EntityTypeBuilder<ChildItem> _)
	{
		_.HasKey(e => e.Id);
		_.Property(e => e.Id).ValueGeneratedNever();

                // semantically each ChildItem is also an Item, hence one-to-one relationship with Id as FK
		_.HasOne(a => a.Parent)
			.WithOne(b => b.Child)
			.IsRequired()
			.HasForeignKey<ChildItem>(a => a.Id);
	}
}

Then this query, which is pretty valid in terms of EF will fail (EF 6 was able to handle that, but EF Core fails as well due to a known bug). Error message is Association key 'ContainerId' not found for type 'ChildItem.

var children = 
    dbContext.Containers
	.Select(c => new
  	    {
		ChildItems = c.ChildItems
			.Select(ch => new
			{
				ContainerId = ch.Parent.ContainerId,
			}),
		})
	.ToLinqToDB()
	.ToArray();

Things work, if I rewrite my query this way, using Items as an entry point and navigating to child in the expression instead of using ChildItems directly.

var children = 
    dbContext.Containers
	.Select(c => new
  	    {
		ChildItems = c.Items
		        .Select(i => i.ChildItem)
			.Select(ch => new
			{
				ContainerId = ch.Parent.ContainerId,
			}),
		})
	.ToLinqToDB()
	.ToArray();

Having said that, do I get it correctly that it’s not possible to have ChildItems collection inside the Container type with linq2db?

Here is a code, if you decide to check it out to improve sth in the libraries. Repro.zip

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:2
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
nforsscommented, May 6, 2021

This issue is not only present in some exotic table setup. I ran into the same with the simplest possible many-to-one relation between two tables, and managed to replicate it in Microsoft’s OData BookStore demo project (slightly modified to use SQLExpress instead of in-memory).

Basically, a query like this

    public IQueryable<Book> Get()
    {
        return _db.Books
            .Where(b => b.Press.Category == Category.Book)
            .ToLinqToDB();
    }

will give the following error

AggregateException: One or more errors occurred. (Association key ‘PressId’ not found for type 'BookStore.Models.Book.)

System.Threading.Tasks.Task<TResult>.GetResultCore(bool waitCompletionNotification)
System.Threading.Tasks.Task<TResult>.get_Result()
LinqToDB.EntityFrameworkCore.Internal.LinqToDBForEFQueryProvider<T>.GetAsyncEnumerator(CancellationToken cancellationToken)
Microsoft.AspNetCore.Mvc.Infrastructure.AsyncEnumerableReader.ReadInternal<T>(object value)
Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsyncEnumerable(ActionContext context, ObjectResult result, object asyncEnumerable, Func<object, Task<ICollection>> reader)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0<TFilter, TFilterAsync>(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Seems like a bug to me. Or am I not using ToLinqToDB() correctly?

Here’s the project: BookStoreDotNet5.zip

0reactions
morganicscommented, Apr 21, 2023

Have found the same behaviour in a 1…* with the child expecting a reference to the parent, using an explicit [ParentName]Id. I’m just trying to use the TempTable as part of EF Core. EF Core can handle the relationship implicitly and I don’t want to start spreading [ParentName]Id in all my model files. It’s really a shame as otherwise it very much fitted my requirements.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Linq2db AssociationAttribute implementation returns an error
It returns an error that says like this. LinqToDB.Linq.LinqException: 'Expression 'Param_0.CreatedBy' is not a Field.
Read more >
LINQ to DB | Linq To DB
POCO will not get ProductID property treated as primary key. And there will be no association with Vendor . This approach is not...
Read more >
Association Mapping - Documentation
A comma-separated list of names of one or more members of the target entity class that represent the key values on the other...
Read more >
[Solved]-LinqToDB with SQLite - reference properties are null-C
This is how I overcame this issue - be aware I was using an Access db. [Table(Name = "Customers")] public class Customer {...
Read more >
Don't use Linq's Join. Navigate! | Passion for Coding
It is not uncommon to see code doing a join manually. ... shows how to do several types of joins, but never mentions...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found