我正在使用EF 4.1中的DBContext
API。
考虑以下实体模型(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)at System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.CreateIsNullExpression(ExpressionConverter parent,Expression输入)at System.Data.Objects.ELinq.ExpressionConverter.EqualsTranslator.TypedTranslate(ExpressionConverter parent,BinaryExpression linq)at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent,Expression linq)
... [更多堆栈跟踪]
在 System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(表达式 linq)at 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()at System.Data.Entity.Infrastructure.DbQuery`1.ToString()
我尝试使用扩展方法形成类似的查询但具有相同的异常。我在这里缺少什么?
-------------------------------------------- -------------------------------------
修改
问题似乎是由于行
Data = null != m ? m.Data : [default value]
我已将其修改为
Data = m
它开始工作了。我必须在我使用结果的地方移动空检查逻辑。现在,我想知道什么是异常的原因?从异常细节来看,它似乎无法找出m(这是一种匿名类型)作为引用类型。这种行为是否记录在某处?
答案 0 :(得分:3)
你是否检查了一个连接的实体,这在sql方面没有意义。以下内容应正确解释为合并:
Data = m.Data ?? [default value]