J'utilise DBContext
API de EF 4.1. envisager de suivre le modèle d'entité (A, B, E, D sont des entités)Comment combiner la jointure interne et la jointure gauche dans Entity Framework
A: AIDE
B: IAD, cid
E: EID, l'aide
D: EID, cid , données
Ce que je veux est équivalent ci-dessous sql requête
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
C'est simple d'avoir quitté la jointure sur B, E & D mais j'ai trouvé que je ne peux pas résoudre la question ci-dessus. J'ai essayé sous forme de LINQ de ce que je pense serait une requête équivalente
// 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]
};
Cependant, cela ne fonctionne pas quand je l'appelle o.ToString()
avec détails suivants d'exception:
System.ArgumentException: L'argument de DbIsNullExpression doit fait référence à un type primitif ou de référence. à System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.ValidateIsNull (DbExpression de l'argument , Boolean allowRowType) à System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.CreateIsNullExpression (parent ExpressionConverter , l'entrée d'expression) à System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate (parent ExpressionConverter , BinaryExpression linq) à System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate (parent ExpressionConverter , expression linq)
... [plus trace de pile ici]
à System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression (Expression linq) à System.Data.Objects.ELinq.ExpressionConverter.Convert()
à System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan (Nullable1 forMergeOption) at System.Data.Objects.ObjectQuery.ToTraceString() at System.Data.Entity.Internal.Linq.InternalQuery
1.ToString() à System.Data.Entity.Infrastructure.DbQuery`1.ToString()
J'ai essayé de former requête similaire en utilisant des méthodes d'extension, mais a la même exception. Qu'est-ce que j'oublie ici?
--------------------------------------------- ------------------------------------
EDIT:
Il semble cette question était due à la ligne
Data = null != m ? m.Data : [default value]
Je l'ai modifié pour
Data = m
Et ça a commencé à fonctionner. Je dois déplacer la logique de vérification nulle à l'endroit où j'utilise le résultat. Maintenant, je me demande ce qui peut être la cause de l'exception? À partir des détails de l'exception, il semble qu'il ne peut pas comprendre m (qui est un type anonyme) comme type de référence. Ce comportement est-il documenté quelque part?
a eu le temps de revoir ce scénario pour le tester! – VinayC