Я использую DBContext
API из EF 4.1.
Рассмотрим следующую модель сущностей (A, B, E, D - сущности)
A: AID
B: AID, CID
E: eId, aId
D: eId, cId, Data
То, что я хочу, эквивалентно приведенному ниже 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
Это просто оставить соединение на B, E & D, но я обнаружил, что не могу решить вышеупомянутый запрос.
Я пробовал linq форму того, что я думаю, будет эквивалентным запросом
// 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]
};
Однако это не удается, когда я звоню o.ToString()
со следующими деталями исключения:
System.ArgumentException: аргумент для DbIsNullExpression должен
обратитесь к примитиву или ссылочному типу. в
System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.ValidateIsNull (DbExpression
аргумент, логическое allowRowType) в
System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.CreateIsNullExpression (ExpressionConverter
родитель, выражение выражения) в
System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate (ExpressionConverter
BinaryExpression linq) в
System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate (ExpressionConverter
родитель, выражение linq)
... [здесь больше трассировки стека]
в
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 ()
Я пытался сформировать подобный запрос, используя методы расширения, но у меня было то же исключение. Что мне здесь не хватает?
-------------------------------------------- -------------------------------------
EDIT:
Похоже, проблема связана со строкой
Data = null != m ? m.Data : [default value]
Я изменил его на
Data = m
И это начало работать. Я должен переместить нулевую логику проверки в то место, где я использую результат. Теперь мне интересно, что может быть причиной исключения? Из подробностей исключения видно, что он не может определить m (который является анонимным типом) как ссылочный тип. Это поведение где-то задокументировано?