Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to join with or condition? Cross Join is creating a IS NULL where clause

Basically I want to create an inner or join. In SQL:

SELECT COUNT(*) FROM Discounts
JOIN DiscountArticles ON Discounts.ID = DiscountArticles.Discount
JOIN Articles ON (DiscountArticles.Article = Articles.ID OR DiscountArticles.ArticleGroup = Articles.ArticleGroup)

This answer says, it’s not possible using entity framework, however we can use an cross join, which works fine on SQL:

SELECT COUNT(*) AS GroupCount FROM Discounts
JOIN DiscountArticles ON Discounts.ID = DiscountArticles.Discount
CROSS JOIN Articles
WHERE (Articles.ID = DiscountArticles.Article OR Articles.ArticleGroup = DiscountArticles.ArticleGroup)

So I tried this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

var query = from discounts in _dbContext.Discounts
    join discountArticles in _dbContext.DiscountArticles on discounts.Id equals discountArticles.Discount
    from article in _dbContext.Articles
    where article.Id == discountArticles.Article || article.ArticleGroup.Value == discountArticles.ArticleGroup.Value
    select new
    {
        ArticleId = article.Id,
        DiscountId = discounts.Id
    };

However, this resolves into this this SQL query:

SELECT [a].[ID] AS [ArticleId], [d].[ID] AS [DiscountId]
FROM [Discounts] AS [d]
INNER JOIN [DiscountArticles] AS [d0] ON [d].[ID] = [d0].[Discount]
CROSS JOIN [Articles] AS [a]
WHERE ([a].[ID] = [d0].[Article]) OR (([a].[ArticleGroup] = [d0].[ArticleGroup]) OR (([a].[ArticleGroup] IS NULL) AND ([d0].[ArticleGroup] IS NULL)))

As you can see, there is an addtional check OR (([a].[ArticleGroup] IS NULL) AND ([d0].[ArticleGroup] IS NULL)), which is causing to return 6 time more results.

ArticleGroup is Nullable Guid? on both entities, so I guess it has something to do with it.

If I additional check it for null, I get the correct results:

where article.Id == discountArticles.Article ||
  article.ArticleGroup.HasValue && article.ArticleGroup == discountArticles.ArticleGroup

However, I also get an bigger where clause in SQL:

WHERE ([a].[ID] = [d0].[Article]) OR (([a].[ArticleGroup] IS NOT NULL) AND ([a].[ArticleGroup] = [d0].[ArticleGroup]))

Is it somehow possible to generate a Query, which is more like my second SQL example? Something like this:

WHERE (Articles.ID = DiscountArticles.Article OR Articles.ArticleGroup = DiscountArticles.ArticleGroup)

>Solution :

Try this query, it will create appropriate join. I do not think that you need CROSS JOIN here.

var query = 
    from discounts in _dbContext.Discounts
    join discountArticles in _dbContext.DiscountArticles on discounts.Id equals discountArticles.Discount
    from article in _dbContext.Articles
        .Where(article => article.Id == discountArticles.Article || article.ArticleGroup.Value == discountArticles.ArticleGroup.Value)
    select new
    {
        ArticleId = article.Id,
        DiscountId = discounts.Id
    };

According to null comparison, check this option Using relational null semantics. Bad here that it will affect all queries:

services.AddDbContext<MyDbContext>(options =>
{
    options.UseSqlServer(sourceConnection, sqlOptions =>
    {
        sqlOptions.UseRelationalNulls();
    });
});
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading