6

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 (Nullable 1 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?

Répondre

2

Eh bien vous étiez null vérifier une entité jointe, ce qui n'a pas de sens en termes de SQL. Ce qui suit devrait être interprété correctement comme un coalesce:

Data = m.Data ?? [default value] 
+0

a eu le temps de revoir ce scénario pour le tester! – VinayC

Questions connexes