无法创建常量值——只允许使用原始类型或枚举类型。

3

我看到一些关于这个异常的问题,但没有一个让我理解问题的根本原因。因此,我们又来了一个...

var testquery = 
((from le in context.LoanEMIs.Include("LoanPmnt")
  join lp in context.LoanPmnts on le.Id equals lp.LoanEMIId
  where lp.PmntDtTm < date && lp.IsPaid == false
  && le.IsActive == true && lp.Amount > 0
  select new ObjGetAllPendingPmntDetails
  {
      Id = lp.Id,
      Table = "LoanEMI",
      loanEMIId = lp.LoanEMIId,
      Name = le.AcHead,
      Ref = SqlFunctions.StringConvert((double)le.FreqId),
      PmntDtTm = lp.PmntDtTm,
      Amount = lp.Amount,
      IsDiscard = lp.IsDiscarded,
      DiscardRemarks = lp.DiscardRemarks
  }).DefaultIfEmpty(ObjNull));

  List<ObjGetAllPendingPmntDetails> test = testquery.ToList();

这个查询出现了以下异常信息 -
无法创建类型为CashVitae.ObjGetAllPendingPmntDetails的常量值。在此上下文中,仅支持原始类型或枚举类型。
我添加SQL函数语句来转换le.FreqId(一个byte)为string时,遇到了这个异常。由于LINQ表达式存储不识别ToString(),因此会出现该异常。
ObjGetAllPendingPmntDetails是我的模型中的部分类,它被添加到代码中的很多位置以将数据绑定到表格。其中包括ID作为long、Amount作为decimal、PmntDtTm作为Datetime,IsDiscard作为bool,剩余属性都是字符串,包括Ref。
当前没有数据满足条件,我得不到结果。在尝试处理null时,我添加了DefaultIfEmpty(ObjNull)并初始化了ObjNull的所有属性如下。
ObjGetAllPendingPmntDetails ObjNull = new ObjGetAllPendingPmntDetails()
{ Id = 0, Table = "-", loanEMIId = 0, Name = "-", Ref = "-",
  PmntDtTm = Convert.ToDateTime("01-01-1900"),
  Amount = 0, IsDiscard = false, DiscardRemarks = "" };

我希望这个查询能够正常工作,因为它在调用 Union() 时还有其他5个查询。所有的查询都返回相同的列 ObjGetAllPendingPmntDetails。但是由于没有符合条件的数据,所以这个查询出现了问题,导致上面提到的异常。如果您有任何建议,请告诉我,因为我无法理解问题的根本原因。

你的 .DefaultIfEmpty(ObjNull) 代码让我觉得有问题。实际上,它看起来并不必要,因为你在结果上调用了 .ToList()。你真的希望在找不到匹配项时返回长度为一的列表吗? - Andrew Coonce
1个回答

3

@AndrewCoonce说得对,.DefaultIfEmpty(ObjNull)是问题所在。Entity Framework将DefaultIfEmpty转换成类似于以下内容的东西...

CASE WHEN ([Project1].[C1] IS NULL) THEN @param ELSE [Project1].[Value] END AS [C1]

...但是没有办法强制将一个ObjGetAllPendingPmntDetails实例转换为可以替代@param的东西,因此会出现异常。

如果将DefaultIfEmpty调用移至ToList之后,它应该就能正常工作了(尽管在那之后你需要再次调用ToList如果你真的想要一个具体的列表实例)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接