6

Używam API DBContext z EF 4.1. Rozważmy następujący wzór jednostka (A, B, E i D są jednostkami)Jak łączyć sprzężenie wewnętrzne i lewe sprzężenie w Entity Framework

A: AID

B: pomoc CID

E: eid, pomocy

D: eid CID , Dane

Co chcę jest odpowiednikiem poniżej zapytania sql

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 

To proste, aby połączyć lewe na B, E & D, ale odkryłem, że nie mogę rozwiązać powyższego zapytania. Próbowałem forma LINQ, co myślę, że byłoby równoważne zapytanie

// 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] 
     }; 

Jednak to się nie powiedzie, gdy zgłoszę o.ToString() z następującymi szczegółami wyjątek:

System.ArgumentException: Argument DbIsNullExpression musi odnoszą się do typu pierwotnego lub odniesienia. w System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.ValidateIsNull (DbExpression argumentów, logiczna allowRowType) w System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.CreateIsNullExpression (ExpressionConverter macierzystego, wejście ekspresji) w System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate (ExpressionConverter dominująca BinaryExpression LINQ) w System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate (ExpressionConverter macierzystego Ekspresja LINQ)

... [więcej śladu stos tutaj]

w System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression (wyrażenie LINQ) w System.Data.Objects.ELinq.ExpressionConverter.Convert()
w System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan (Nullable 1 forMergeOption) at System.Data.Objects.ObjectQuery.ToTraceString() at System.Data.Entity.Internal.Linq.InternalQuery 1.ToString() w System.Data.Entity.Infrastructure.DbQuery`1.ToString()

I próbowali formie podobnej zapytanie przy użyciu metod przedłużenie, miała taki sam wyjątek. Czego tu mi brakuje?

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

EDIT:

It wydaje się, że problem był spowodowany linii

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

zmodyfikowałem go

Data = m 

I zaczęło działać. Muszę przenieść logikę zerową sprawdzając w miejscu, w którym używam wyniku. Teraz zastanawiam się, co może być przyczyną wyjątku? Z informacji o wyjątkach okazuje się, że nie może on określić m (który jest typem anonimowym) jako typu odniesienia. Czy to zachowanie jest gdzieś udokumentowane?

Odpowiedz

2

Cóż, masz zerowe sprawdzanie połączonego podmiotu, co nie ma sensu pod względem sql. Poniższe informacje należy interpretować poprawnie jako połączenie:

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

otrzymałem czas na ponowne zapoznanie się z tym scenariuszem, aby go przetestować! – VinayC

Powiązane problemy