使用int调用和计算函数时出错?作为输入

时间:2014-02-01 19:59:35

标签: c#

我有这样的功能:

public int? calculateContractPrice(int? comid)
{
    int? sum = 0;
    var q = from i in dbconnect.tblMaterialGroups
            where i.tenderId == _tenderId
            select i.id;
    foreach (int i in q )
    {
        var q2 = from g in dbconnect.tblMaterialTenderAnnouncePrices
                 where g.MaterialGroupId == i && g.companyId == comid
                 select g;
        sum = q2.First().amount*q2.First().price + q2.First().amount*q2.First().PriceForElse + sum;


    }
    return sum ;
}

当我尝试执行此操作时:

List<presentationcontract> q = (from i in dbconnect.tblContracts
                                where i.tender == _tenderId
                                select new presentationcontract()
                                    {                                            
                                         tax =(calculateContractPrice(i.companyId)*(6/100)).ToString()

                                    }).ToList();

税是字符串。执行后我收到此错误:

couldn't translate expression calculateContractPrice(i.companyId)*(6/100),invoke(value(system.Func1[system.nullable1[system.Int32]]))).ToString() into SQL and could not treat it as a local expression 

2 个答案:

答案 0 :(得分:2)

您的修改可以解决问题。你正试图做

tax =(calculateContractPrice(i.companyId)*(6/100)).ToString()

在sql语句中但calculateContractPrice在c#中!要了解发生了什么,您真的需要了解LINQ的工作原理。

首先,停止对LINQ使用愚蠢的sql样式语法。它没有lambda语法那么强大,并且以一种难以理解的方式隐藏了幕后的内容。

其次考虑一个LINQ语句

users.Where(u => u.Name == "George").ToList();

用户为IEnumerable<User>。这里发生的是lambda部分是Func<User, bool>类型,并被编译为一个方法,该方法针对User的每个实例运行。

现在考虑这个LINQ语句

db.Users.Where(u => u.Name == "George").ToList();

其中db.UsersIQueryable<T>。这看起来一样,但发生的情况非常不同。会发生什么是lambda实际上是Expression<Func<User, bool>>类型,它不会被编译到方法,而是被编译成一个叫做表达式树的东西。这将传递给LINQ提供程序(在您的情况下,我正在猜测的实体框架),它检查它并将其转换为SQL语句

SELECT Id, Name, Address FROM users WHERE Name = 'George'

在您的情况下发生的事情是,它看到了对calculateContractPrice的调用,并且无法将其转换为SQL。

您应该做的是确保首先运行查询,然后使用在c#中运行的IEnumerable<T>形式的LINQ来调用您的方法。

var contracts = dbconnect.tblContracts.Where(i => i.tender == _tenderId)
                 .ToList()   //Query executes here, now you have IEnumerable<T>
                 .Select(i => new PresentationContract {
                                  Tax = ...
                              }).ToList();  //this ToList is only necessary if you want to prevent multiple iteration

你当然希望解决其他人指出的所有其他问题。

其他一些注意事项 - 您需要阅读.Net命名约定。通常,建议任何公共,受保护或内部(类,字段,属性等)为PascalCase。您也可能希望将分区部分移动到PresentationContract类中。这个具有Tax属性的类应该是知道如何生成它的类。

答案 1 :(得分:0)

试试这个:

int? ret = calculateContractPrice(i.companyId);
if(ret.HasValue)
{
    tax =(ret.Value*(6/100)).ToString();
}

您应该确保该函数确实返回了一个值,然后在计算中使用该整数值。