我有这样的功能:
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
答案 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.Users
为IQueryable<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();
}
您应该确保该函数确实返回了一个值,然后在计算中使用该整数值。