Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Association] with QueryExpressionMethod does not honor CanBeNull property #4454

Open
shameleo opened this issue Mar 19, 2024 · 3 comments
Open

Comments

@shameleo
Copy link

Describe your issue

If CanBeNull is false, I would expect generated SQL to use INNER JOIN or CROSS APPLY. But it uses LEFT JOIN or OUTER APPLY instead.

Steps to reproduce

    public class Client
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class Service
    {
        public int Id { get; set; }
        public int? IdClient { get; set; }

        //[Association(ThisKey = nameof(IdClient), OtherKey = nameof(l2db_bug.Client.Id), CanBeNull = false)]
        //[Association(ExpressionPredicate = nameof(Client_ExprPr), CanBeNull = false)]
        [Association(QueryExpressionMethod = nameof(Client_QExpr), CanBeNull = false)]
        public Client Client { get; set; }

        // works fine
        //static Expression<Func<Service, Client, bool>> Client_ExprPr =>
        //    (s, c) => s.IdClient == s.Id;

        // always generates left join or outer apply (if query is more complicated)
        static Expression<Func<Service, IDataContext, IQueryable<Client>>> Client_QExpr =>
            (s, db) => db.GetTable<Client>().Where(c => c.Id == s.IdClient);
    }
var q_clientNames = db.GetTable<Service>().Select(s => s.Client.Name);

Environment details

Linq To DB version: 5.4.0

Database (with version): SQL Server 2008

ADO.NET Provider (with version): Microsoft.Data.SqlClient 4.1.0

.NET Version: .NET Core 2.1

@sdanyliv
Copy link
Member

It is not a bug, we have special code which ignores CanBeNull for complex associations. Does it make performance isssues for your queries?

@jods4
Copy link
Contributor

jods4 commented Mar 19, 2024

This looks like a dupe of #3658, which was supposedly fixed in 5.0.0.
Did the fix not cover all types of associations?

@shameleo
Copy link
Author

shameleo commented Mar 22, 2024

It is not a bug, we have special code which ignores CanBeNull for complex associations.

For what reason?
Also, QueryableAssociationTests.cs and some other tests use QueryExpressionMethod and CanBeNull combination.

Does it make performance isssues for your queries?

No, it doesn't. At least for now. It's more about correctness. I don't know what is the point of CanBeNull attribute, but I understand it as not like hint (CanBeNull = false, so I promise you that every Service references to Client"), but like forced requirement (CanBeNull = false, so I if any Service does not references to Client - skip it). Of course I can add where ... is not null, but it's not great workaround, as if association is changed later (like I just did), all queries using it should be fixed.

This looks like a dupe of #3658, which was supposedly fixed in 5.0.0.

I tested with SqlServer and Sqlite. Queries was slighly different, but I doubt it matters. CanBeNull with QueryExpressionMethod was ignored in both cases. CanBeNull with ExpressionPredicate was ignored in Sqlite, but not in SqlServer. It's weird.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants