简体   繁体   中英

Int.Parse in Linq Expression

I have the following LINQ expression. I want calculate the sum of numeric values in an nvarchar field. I'm using following code to do this, but I get an error when I try to run this.

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();

Error Description:

LINQ to Entities does not recognize the method 'Int32 Parse(System.String)' method, and this method cannot be translated into a store expression

How can I solve this problem and write this code better than this?

I changed the code to this:

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();

but got this error:在此处输入图像描述

EF 5:

Instead of int.Pasrse use Convert.ToInt32 . Entity Framework will generate proper CAST functions in SQL.

EF 6:

Short answer:

youEntity.Where(c=>SqlFunctions.StringConvert((decimal?)c.INTFIELD).Trim() == STRINGVALUE)

Long answer:

in EF 6 you have to convert numeric value to string with SqlFunctions.StringConvert . but it has a problem. It will add unnecessary spaces to the result. so the comparison will fail. That's why I have put Trim() there. I have tested it with EF 6.1.1.

Replace all your int.Parse by SqlFunctions.StringConvert(variable) . There's no function to convert String to Int. You should try to do the inverse and convert your Int to String with StringConvert.

The SqlFunctions utilities will be able to translate the command in SQL command.

Entity Framework can't translate that type of conversion to SQL.

Is there any chance you could alter your data structure to use proper data types such as actual DateTime types? For large data volumes conversions like that will affect performance.

I would recommend either changing your data model types to avoid these conversions, or if the amount of data will always be small , then get the data first, and later use Linq to Objects.

In your where clause, you can't call int.Parse . Entity Framework doesn't know how to convert that to SQL. Consider revising your Where .

You can't use int.parse in where . You can rewrite your query like this:

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();

Call .ToList() method, then use int.Parse(variable) .

Have a nice day.

If you need a lot, I recommend CodeFirstStoreFunctions .

Step0 -> CodeFirstStoreFunctions nuget install

Step1-> Create a simple sql scalar functions

 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

Step2 -> add in OnModelCreating

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

Step3 -> build in the SqlHelper class

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

Result -> 在此处输入图像描述

When you need to make sure a CLR method can be used in LINQ to Entities you'd better consult this source: https://msdn.microsoft.com/en-us/library/vstudio/dd456828(v=vs.100).aspx .

Not a fast reading, it'd take time, but here's the answer to your question (and many more like it).

There is a badly built database, which I cannot edit, but have to use it.

I use this in Linq-To-Sql and it works.

First cast the string to object, then cast it to 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))),
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM