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.

Associations with ExpressionPredicate are lost when query is joined

See original GitHub issue

The test entity:

[Table(Name = User.TableName)]
	public class User : EntityBase
	{
		internal const string TableName = "Users";

		[PrimaryKey, Identity]
		[Column(Name = "Id")]
		public override int Id { get; set; }

		[Column(Name = "Name")]
		public string Name { get; set; }

		[Column(Name = "IsActive")]
		public bool IsActive { get; set; }

		[Column(Name = "Guid")]
		public Guid Guid { get; set; }

		[Column(Name = "AppointmentId")]
		public int? AppointmentId { get; set; }

		[Association(ThisKey = "AppointmentId", OtherKey = "Id", CanBeNull = true, Relationship = Relationship.ManyToOne,
			KeyName = "FK_Users_AppointmentId",
			BackReferenceName = "Users")]
		public virtual Appointment Appointment { get; set; }

		[Column]
		public int? ParentUserId { get; set; }

		[Association(CanBeNull = true, ExpressionPredicate = nameof(ParentPredicate))]
		public User Parent { get; set; }

		public static Expression<Func<User, User, bool>> ParentPredicate => (u1, u2) =>
		  u1.ParentUserId == u2.Id && u2.IsActive;
	}

Test methods

[Test]
public void Linq2DBOtherTests_Bug_With_Expression_Predicate_OK()
{
	using (var db = GetDataConnection())
	{
		var q123 = from x in db.GetTable<User>()
					select new
					{
						x.Id,
						ParentName = x.Parent.Name,
						AppointmentName = x.Appointment.Name
					};

		q123.ToList();
	}
}

[Test]
public void Linq2DBOtherTests_Bug_With_Expression_Predicate_Fail()
{
	using (var db = GetDataConnection())
	{
		// something to join. Anything. Let's say, that here is id selection from some permission view
		var p1 = db.Users.Where(x => x.Id == 123);

		var q123 = from x in db.GetTable<User>()
					join p in p1 on x.Id equals p.Id
					select new
					{
						x.Id,
						ParentName = x.Parent.Name,
						AppointmentName = x.Appointment.Name
					};

		q123.ToList();
	}
}

Without joining associations properties selection works well:

SELECT
	[t3].[Id],
	[t1].[Name],
	[t2].[Name] as [Name1]
FROM
	[Users] [t3] WITH (NOLOCK)
		LEFT JOIN [Users] [t1] ON [t3].[ParentUserId] = [t1].[Id] AND 1 = [t1].[IsActive]
		LEFT JOIN [Appointments] [t2] ON [t3].[AppointmentId] = [t2].[Id]

But with any join generated SQL doesn’t have selection for association properties

SELECT
	[x].[Id]
FROM
	[Users] [x] WITH (NOLOCK)
WHERE
	[x].[Id] = 123

Environment details

linq2db: 2.0.0 provider: SqlServerVersion.v2012

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
sdanylivcommented, Sep 5, 2018

It is not easy, but why not to start 😃 It took 2 years for me to understand 80% of code. Start from setting break-point to AssociationDescriptor constructor.

0reactions
sdanylivcommented, Sep 6, 2018

Great, saving our time 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Applying a predicate to a joined table
This does return you "a bunch of users" like the other queries do ( ctx.Users.Where(nameIsBob) ), but you've lost the event unless you...
Read more >
SA0051 : The query is missing a join predicate. This may ...
The rule checks the T-SQL code for queries having joined tables and missing join a predicate for one of the tables. It identifies...
Read more >
How to design SQL queries with better performance
In the article, we will talk about the various operators and what do they do, when do they come and what happens when...
Read more >
Overview of Predicates | InterSystems SQL Reference
A predicate is a condition expression that evaluates to a boolean value, either true or false. Predicates can be used as follows: In...
Read more >
Query and Reporting : Joining Tables
If you join two tables that both have missing rows, you can combine the effect of a ... This saves you from defining...
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