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?