简体   繁体   中英

Call method from within Linq query

If I have the query below :-

var Values = from data in DtSet.Tables["tblCosts"].AsEnumerable()
            group data by new
            {
                InvNo = data.Field<double>("InvoiceNo"),
                AccRef = data.Field<double>("SiteRefNum"),
            }
            into g
            select new
            {
                Code = "1",
                InvType = "I",
                Account = g.Key.AccRef,
                InvNo = g.Key.InvNo,
                ChargeType = ***********
            };

...how I can I call a separate method CalcChargeType (which returns a string, based on the value in the InvNo column) and have the returned value go into column ChargeType, as, from what I've read, methods cannot be translated into Linq/SQL.

from what I've read, methods cannot be translated into Linq/SQL.

But you are not using Linq-To-Sql but Linq-To-DataSet which is a subset of Linq-To-Objects .

So yes, you can do all that you can do without Linq, fe calling a method:

var Values = from data in DtSet.Tables["tblCosts"].AsEnumerable()
        group data by new
        {
            InvNo = data.Field<double>("InvoiceNo"),
            AccRef = data.Field<double>("SiteRefNum"),
        }
        into g 
        select new
        {
            Code = "1",
            InvType = "I",
            Account = g.Key.AccRef,
            InvNo = g.Key.InvNo,
            ChargeType = CalcChargeType(g.Key.InvNo)
        };

Have you tried ?

var Values = from data in DtSet.Tables["tblCosts"].AsEnumerable()
            group data by new
            {
                InvNo = data.Field<double>("InvoiceNo"),
                AccRef = data.Field<double>("SiteRefNum"),
            }
            into g
            select new
            {
                Code = "1",
                InvType = "I",
                Account = g.Key.AccRef,
                InvNo = g.Key.InvNo,
                ChargeType = CalcChargeType(g.Key.InvNo)
            };

The, when you will evaluate the query (with ToList() for example), CalcChargeType will be called/

Since this is not Linq to SQL you may call it without problems.

By casting the first part of query to .AsEnumerable() you have fetched all data in the tblCosts table to the memory. Now it is not a Linq to SQL query, but an in memory linq query.

You'd have to evaluate the query (by calling .ToList() ), then re-select and call the function, like so:

var Values = (from data in DtSet.Tables["tblCosts"].AsEnumerable()
        group data by new
        {
            InvNo = data.Field<double>("InvoiceNo"),
            AccRef = data.Field<double>("SiteRefNum"),
        }
        into g)
        .ToList()
        .Select(g => new
        {
            Code = "1",
            InvType = "I",
            Account = g.Key.AccRef,
            InvNo = g.Key.InvNo,
            ChargeType = CalcChargeType(g.Key.ChargeType)
        };

Well you could try :

var Values = from data in DtSet.Tables["tblCosts"].AsEnumerable()
        group data by new
        {
            InvNo = data.Field<double>("InvoiceNo"),
            AccRef = data.Field<double>("SiteRefNum"),
        }
        into g
        select new
        {
            Code = "1",
            InvType = "I",
            Account = g.Key.AccRef,
            InvNo = g.Key.InvNo,
            ChargeType = CalcChargeType(g.Key.InvNo)
        };

Since you're using DataSet extensions and not Linq-to-SQL I bet it would work. If your Linq provider doesn't support it, your next bet is to hydrate what you can and add the ChargeType column afterwards:

var Values = (from data in DtSet.Tables["tblCosts"].AsEnumerable()
        group data by new
        {
            InvNo = data.Field<double>("InvoiceNo"),
            AccRef = data.Field<double>("SiteRefNum"),
        }
        into g).ToList() // hydrate the query
        .Select(g=> new
        {
            Code = "1",
            InvType = "I",
            Account = g.Key.AccRef,
            InvNo = g.Key.InvNo,
            ChargeType = CalcChargeType(g.Key.InvNo)
        });

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