How to combine inner join and left join in Entity Framework

I am using the DBContext API from EF 4.1. Consider the following entity model (A, B, E, D - entities)

A: aId

B: aId, cId

E: eId, aId

D: eId, cId, Data p>

What I want is equivalent to below sql query

 SELECT B.aId, B.cId, COALESCE(M.Data, [default value]) FROM B LEFT OUTER JOIN ( SELECT E.aId, D.cId, D.Data FROM E INNER JOIN D ON E.eId = D.eId ) M ON B.aId = M.aId AND B.cId = M.cId 

A simple left join on B, E and D, but I found that I cannot solve the above request. I tried the linq form of what, in my opinion, would be an equivalent query

 // inner join equivalent var ee = db.E.Join(db.D, e => e.eId, d => d.eId, (e, d) => new { e.aId, e.eId, d.cId, d.Data }); // left outer join var o = from c in db.B join e in ee on new { c.aId, c.cId } equals new { e.aId, e.cId } into temp from m in temp.DefaultIfEmpty() select new { c.aId, c.cId, Data = null != m ? m.Data : [default value] }; 

However, this fails when I call o.ToString() with the following exception details:

System.ArgumentException: The argument for DbIsNullExpression should refer to a primitive or reference type. in System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.ValidateIsNull (DbExpression argument, Boolean allowRowType) in System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.CreateIsNullExpression Express (Express) .ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate (ExpressionConverter parent, BinaryExpression linq) in System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate (ExpressionConverter parent, Expression linq)

... [more stack trace here]

in System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression (Expression linq) in System.Data.Objects.ELinq.ExpressionConverter.Convert ()
at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan (Nullable 1 forMergeOption) at System.Data.Objects.ObjectQuery.ToTraceString() at System.Data.Entity.Internal.Linq.InternalQuery 1.ToString () .Entity.Infrastructure.DbQuery`1.ToString ()

I tried to generate a similar request using extension methods, but had the same exception. What am I missing here?

-------------------------------------------- ------ -------------------------------

EDIT:

It seems that the problem arose due to the line

 Data = null != m ? m.Data : [default value] 

I changed it to

  Data = m 

And he began to work. I need to move the null check logic to where I use the result. Now, I wonder what could be causing the exception? From the details of the exception, it looks like it cannot define m (which is an anonymous type) as a reference type. Is this documented somewhere?

+6
source share
1 answer

Well, you were a null check on a merged object, which does not make sense in terms of sql. The following should be construed correctly as a union:

 Data = m.Data ?? [default value] 
+2
source

Source: https://habr.com/ru/post/894805/


All Articles