使用LINQ进行整数转换

5
以下LINQ中有一些Convert.ToInt32方法。但它不起作用。参考互联网,应该使用int.Parse而不是convert。仍然会出错。请指导我如何做。
在下面的查询中,tody的数据类型是DateTime
var ds = (from a in dbSetInvHeader
          join b in dbSetCustomer on a.BusinessEntityID equals b.Id
          join c in dbSetFinancialInfo on b.Id equals c.Id
          where (a.TotalAmount - a.AppliedAmount - a.ApplyToInvoiceCreditAmount) > 0
                      && DbFunctions.AddDays(a.InvoiceDate, Convert.ToInt32(c.CreditPeriod)) >= tody
          select new OverDueInvoices
                      {
                          CustomerName = b.Name,
                          InvoiceNo = a.InvoiceNo,
                          InvoiceAmount = a.TotalAmount - a.ApplyToInvoiceCreditAmount,
                          DueAmount = (a.TotalAmount - a.AppliedAmount - a.ApplyToInvoiceCreditAmount),
                          CreditAmount = a.ApplyToInvoiceCreditAmount,
                          NoOfDays = Convert.ToInt32(DbFunctions.DiffDays(tody, a.InvoiceDate))
                      }).ToList();

更新:

以上的LINQ代码使用了Entity Framework,会导致错误:

当使用Convert.ToInt32时:

"LINQ to Entities不识别方法'Int32 ToInt32(System.Decimal)',并且无法将此方法转换为存储表达式。"

当使用int.Parse时:

"LINQ to Entities不识别方法'Int32 Parse(System.String)',并且无法将此方法转换为存储表达式。"


被抛出的错误是什么? - Chris Cruz
尝试使用 EntityFunctions - Lei Yang
我添加了“更新1”,并提供了更多细节。 - weeraa
就我所知,DbFunctions.DiffDays 已经返回了一个 Nullable<int>。你对 Convert.ToInt32 方法有什么期望? - grek40
@Lei Yang:提供的链接中所有函数的输入变量都是可空整数。但是在我的LINQ中,“dbSetFinancialInfo”具有“CreditPeriod”字段,它是十进制类型。无法更改数据类型为int,因为已经使用现有数据类型进行了大量开发。像这种情况下,我们必须在LINQ中强制转换数据类型。难道不是吗? - weeraa
@grek40: "NoOfDays" 的数据类型是 int。我们可以直接将 nullable<int> 分配给 int 数据类型吗?难道我们不需要进行强制转换吗? - weeraa
3个回答

1

SQL不知道Convert.ToInt32函数。在Entity Framework中似乎没有将字符串转换为整数的解决方法。您可以做的是向您的对象添加另一列NoOfDaysString。

public string NoOfDaysString {get; set;}
public string NoOfDays {get { return  Convert.ToInt32(NoOfDaysString); } ;}

将您的查询重写为以下格式。
var ds = (from a in dbSetInvHeader
                  join b in dbSetCustomer on a.BusinessEntityID equals b.Id
                  join c in dbSetFinancialInfo on b.Id equals c.Id
                  where (a.TotalAmount - a.AppliedAmount - a.ApplyToInvoiceCreditAmount) > 0
                  && DbFunctions.AddDays(a.InvoiceDate, Convert.ToInt32(c.CreditPeriod)) >= tody
                  select new OverDueInvoices
                  {
                      CustomerName = b.Name,
                      InvoiceNo = a.InvoiceNo,
                      InvoiceAmount = a.TotalAmount - a.ApplyToInvoiceCreditAmount,
                      DueAmount = (a.TotalAmount - a.AppliedAmount - a.ApplyToInvoiceCreditAmount),
                      CreditAmount = a.ApplyToInvoiceCreditAmount,
                      NoOfDaysString = Convert.ToInt32(DbFunctions.DiffDays(tody, a.InvoiceDate))

                  }).ToList();

这是我能想到的唯一解决where语句的方法。在对象中添加CreditPeriod,并在对象加载到内存后进行where筛选。
var ds = (from a in dbSetInvHeader
              join b in dbSetCustomer on a.BusinessEntityID equals b.Id
              join c in dbSetFinancialInfo on b.Id equals c.Id
              where (a.TotalAmount - a.AppliedAmount - a.ApplyToInvoiceCreditAmount) > 0
              select new OverDueInvoices
              {
                  CustomerName = b.Name,
                  InvoiceNo = a.InvoiceNo,
                  InvoiceAmount = a.TotalAmount - a.ApplyToInvoiceCreditAmount,
                  DueAmount = (a.TotalAmount - a.AppliedAmount - a.ApplyToInvoiceCreditAmount),
                  CreditAmount = a.ApplyToInvoiceCreditAmount,
                  NoOfDaysString = Convert.ToInt32(DbFunctions.DiffDays(tody, a.InvoiceDate))
                  CreditPeriod = c.CreditPeriod
              })ToList().Where(t=>Convert.ToInt32(t.CreditPeriod) >= NoOfDays).ToList();

谢谢。实际上,您提到的方法是有效的。但是在WHERE条件中还有其他转换部分。我尝试做同样的事情,包括一个名为“intCreditDays”的新属性。但是出现了“指定的类型成员'intCreditDays'不受LINQ to Entities支持。仅支持初始化程序、实体成员和实体导航属性。”的错误。 - weeraa
你尝试过像Mikhail Neofitov建议的那样将它转换为int类型(int?)c.CreditPeriod吗? - Liviu Boboia

1
正如@LiviuBoboia所指出的那样,SQL不知道Convert.ToInt32int.Parse方法,因此EF无法正确地将对这些方法的调用转换为SQL。 您可以进行简单的强制转换来替代它们:
NoOfDaysString = (int)DbFunctions.DiffDays(tody, a.InvoiceDate)

这个转换将被转化为SQL函数CONVERT,应该能够正常工作。
虽然DbFunctions.DiffDays返回一个Nullable<int>int?,所以最好避免将其强制转换为(int),因为在尝试将null转换为int时可能会出现InvalidCastException

int?Nullable<int>的语法糖。 - grek40
@grek40 是的,我知道。我猜,OP更熟悉这个语法糖版本,而不是实际名称。 - Mikhail Tulubaev

0

DbFunctions.DiffDays(tody, a.InvoiceDate) 返回一个 Nullable<int>,所以请尝试以下方法之一,而不是使用 Convert.ToInt32

DbFunctions.DiffDays(tody, a.InvoiceDate).GetValueOrDefault();
DbFunctions.DiffDays(tody, a.InvoiceDate) ?? someIntegerDefaultValue;
DbFunctions.DiffDays(tody, a.InvoiceDate).Value;

第一种情况是当你知道结果可能为null,并且你想在这种情况下得到0。第二种情况是当你想要一个不同的默认值或计算一些更复杂的替换时。第三种情况是当你知道结果永远不应该为null,并且如果它为null,你可以接受异常。


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