Linq表达式中的内部分析

5us2dqdw  于 2022-12-25  发布在  其他
关注(0)|答案(8)|浏览(155)

我有下面的LINQ表达式。我想计算nvarchar字段中数值的总和。我使用下面的代码来完成这个任务,但是当我尝试运行这个代码时,我得到了一个错误。

var m = new MaterialModelContainer();

var list = 
    (from x in
        (
            from inv in m.INVs
            join l in m.LIBs on inv.MESC equals l.MESC
            join o in m.OUTs on inv.MESC equals o.MESC
            join t in m.TRANs on inv.MESC equals t.MESC
            where t.TYPE == "60"
            select new
            {
                l.MESC,
                l.LINE_NO,
                l.UNIT_LINE,
                Description = l.DES + " " + l.PART_NO,
                inv.NEW_QTY,
                o.PJ,
                o.DATE,
                o.QTY,
                o.QTY_REC,
                TranQty = t.QTY,
                tranDate = t.DATE
            }
        )
        group x by
            new
            {
                x.MESC,
                x.LINE_NO,
                x.UNIT_LINE,
                x.Description,
                x.NEW_QTY,
                x.PJ,
                x.DATE,
                x.QTY,
                x.QTY_REC
            }
        into g
        select new
        {
            QTY_Consum_1 = g.Where(c => int.Parse(c.tranDate) >= cuDate && int.Parse(c.tranDate) <= endDate).Sum(d => int.Parse(d.TranQty))
        }
    ).ToList();

错误描述:

LINQ to Entities无法识别方法“Int32 Parse(System.String)",因此无法将此方法转换为存储表达式
我怎样才能解决这个问题并写出比这更好的代码呢?
我把密码改成了:

select new
{
    QTY_Consum_1 = g.Where(c => SqlFunctions.StringConvert(c.tranDate) >= cuDate && SqlFunctions.StringConvert(c.tranDate) <= endDate).Sum(d => SqlFunctions.StringConvert(d.TranQty)),
   g.Key.MESC
}
).ToList();

但得到了这个错误:

arknldoa

arknldoa1#

EF 5:

使用Convert.ToInt32代替int.Parse。实体框架将在SQL中生成正确的CAST函数。

EF 6:

  • 简短答案:*
youEntity.Where(c=>SqlFunctions.StringConvert((decimal?)c.INTFIELD).Trim() == STRINGVALUE)
  • 详细答案:*

在EF 6中你必须用SqlFunctions.StringConvert把数值转换成字符串。但是它有一个问题。它会在结果中添加不必要的空格。所以比较会失败。这就是为什么我把Trim()放在那里。我已经用EF 6.1.1测试过了。

fruv7luv

fruv7luv2#

实体框架无法将该类型的转换转换为SQL。
您是否有可能更改数据结构以使用正确的数据类型,例如实际的DateTime类型?对于大数据量,这样的转换会影响性能。
我建议您要么更改数据模型类型以避免这些转换,要么如果数据量总是很小,则先获取数据,然后再使用Linq to Objects。

yqhsw0fo

yqhsw0fo3#

在where子句中不能调用int.Parse,实体框架不知道如何将其转换为SQL,请考虑修改Where

li9yvcax

li9yvcax4#

你不能在where中使用int.parse,你可以这样重写你的查询:

var list = (from x in
                (
                    from inv in m.INVs
                    join l in m.LIBs on inv.MESC equals l.MESC
                    join o in m.OUTs on inv.MESC equals o.MESC
                    join t in m.TRANs on inv.MESC equals t.MESC
                    where t.TYPE == "60" && t.QTY!=""
                    select new
                       {
                           l.MESC,
                           l.LINE_NO,
                           l.UNIT_LINE,
                           Description = l.DES + " " + l.PART_NO,
                           inv.NEW_QTY,
                           o.PJ,
                           o.DATE,
                           o.QTY,
                           o.QTY_REC,
                           TranQty = t.QTY,
                           tranDate = t.DATE

                      }
                ).ToList()
            group x by
                new
                    {
                        x.MESC,
                        x.LINE_NO,
                        x.UNIT_LINE,
                        x.Description,
                        x.NEW_QTY,
                        x.PJ,
                        x.DATE,
                        x.QTY,
                        x.QTY_REC
                    }
            into g
            select new
                {
                    QTY_Consum_1 = g.Where(c => int.Parse(c.tranDate) >= cuDate && int.Parse(c.tranDate) <= endDate).Sum(d => int.Parse(d.TranQty)),
                    g.Key.MESC
                }
           ).ToList();

调用.ToList()方法,然后使用int.Parse(variable)
祝你愉快。

jdg4fx2g

jdg4fx2g5#

将所有的int.Parse替换为SqlFunctions.StringConvert(variable)。没有函数可以将String转换为Int。您应该尝试反向操作,使用StringConvert将Int转换为String。
SqlFunctions实用程序将能够将该命令转换为SQL命令。

slmsl1lt

slmsl1lt6#

如果你需要很多,我推荐CodeFirstStoreFunctions
步骤0-〉CodeFirstStoreFunctions块安装
步骤1-〉创建简单的sql标量函数

CREATE FUNCTION [dbo].[ToInt32](@Value VARCHAR(255)) 
 RETURNS INT
 AS
 BEGIN
 RETURN CONVERT(INT, (CASE WHEN ISNUMERIC(@Value) = 1 THEN @Value ELSE 
 '0' END))
 END

步骤2-〉在OnModel中添加创建

mb.Conventions.Add(new FunctionsConvention("dbo", typeof(SqlHelper)));

步骤3-〉在SqlHelper类中构建

[DbFunction("CodeFirstDatabaseSchema", "ToInt32")]
public static int ToInt32(string value) => throw new NotSupportedException();

结果-〉

holgip5t

holgip5t7#

当你需要确保CLR方法可以在LINQ to Entities中使用时,你最好参考以下源代码:https://msdn.microsoft.com/en-us/library/vstudio/dd456828(v=vs.100).aspx.
这不是一个快速的阅读,这需要时间,但这里是你的问题的答案(和许多喜欢它)。

bybem2ql

bybem2ql8#

有一个建得很糟糕的数据库,我无法编辑,但不得不使用它。
我在Linq-To-Sql中使用了它,它工作正常。
先将字符串转换为object,然后再转换为int。

from s in db.Students
 select new
 {
     s.Name,
     s.Surname,
     Birthday = new DateTime((int)(object)(s.dateStr.Substring(0, 4)),
                             (int)(object)(s.dateStr.Substring(4, 2)),
                             (int)(object)(s.dateStr.Substring(6, 2))),
 }

相关问题