问题描述
假设我们的表T分别具有两个A和B列的表T,分别具有浮点和金钱类型.我想编写一个LINQ查询,例如以下T-SQL语句:
Select A, B, A * B as C From SomeTable Where C < 1000
我试图像以下
一样铸造var list = (from row in model.Table where ((decimal)row.A) * row.B < 1000 select new { A = row.A, B = row.B , C = ((decimal)row.A) * row.B} ).ToList();
,但不允许铸造操作.它引发了一个例外:
在LINQ中不支持将其铸造为小数,因为 无法推断所需的精度和比例信息.
我的问题是如何将双重转换为Linq中的小数?我不想从数据库获取数据.
更新:
我注意到将十进制转换为双重工作,但反向操作引发了异常.所以,
为什么我们不能将双重转换为十进制? SQL Server在T-SQL中也执行相同的机制吗?它不会影响精度吗?
推荐答案
浮子(双)和小数点之间的差异是浮子是十进制精确的.如果您给Float的值为10.123,则在内部可能具有一个值10.1229999999999,它非常接近10.123,但不完全是.
x小数的精度始终是准确的,直到x-the小数为止.
.您数据库的设计师认为A型不需要十进制准确性(或者他只是粗心).比输入参数更精确的计算结果是没有意义的.
如果您确实需要将结果转换为十进制,请将您的公式计算为float/double,并在可唤起后的小数:
时将其计算为十进制.(我对您的语法不太熟悉,所以我将使用扩展方法语法)
var list = model.Table.Where(row => row.A * row.B < 1000) .Select(row => new { A = row.A, B = row.B, }) .AsEnumerable() .Select(row => new { A = row.A, B = row.B, C = (decimal)row.A * (decimal)row.B, });
含义:
- 从我的表中,仅取值的行 <1000.
- 从每个选定的行中,从列A和B. 中选择值
- 将这两个值传输到本地内存(=可触及的),
- 对于每个传输行,创建一个具有三个属性的新对象:
- a和b具有传输的值.
- C获取转移A和B 的十进制值的乘积
其他推荐答案
您可以避免Asenumerable()向实体解释您想要多少分数.
var list = (from row in model.Table where ((decimal)row.A) * row.B < 1000 select new { A = row.A, B = row.B , C = (((decimal)((int)row.A)*100))/100) * row.B} ).ToList();
问题描述
Suppose we have table T which has two columns A and B with float and money types respectively. I want to write a linq query like following T-SQL statement:
Select A, B, A * B as C From SomeTable Where C < 1000
I tried to cast like following
var list = (from row in model.Table where ((decimal)row.A) * row.B < 1000 select new { A = row.A, B = row.B , C = ((decimal)row.A) * row.B} ).ToList();
but it does not allow the cast operation. It throw an exception:
Casting to Decimal is not supported in Linq to Entity queries, because the required precision and scale information cannot be inferred.
My question is how to convert double to decimal in Linq? I don't want to fetch data from database.
Update:
I notice the converting decimal to double works but reverse operation throws the exception. So,
Why can't we convert double to decimal? Does Sql server do the same mechanism in t-sql too? Doesn't it affect precision?
推荐答案
The difference between a float (double) and a decimal, is that a float is decimal precise. If you give the float a value of 10.123, then internally it could have a value 10.1229999999999, which is very near to 10.123, but not exactly.
A decimal with a precision of x decimals will always be accurate until the x-th decimal.
The designer of your database thought that type A didn't need decimal accuracy (or he was just careless). It is not meaningful to give the result of a calculation more precision than the input parameters.
If you really need to convert your result into a decimal, calculate your formula as float / double, and cast to decimal after AsEnumerable:
(I'm not very familiar with your syntax, so I'll use the extension method syntax)
var list = model.Table.Where(row => row.A * row.B < 1000) .Select(row => new { A = row.A, B = row.B, }) .AsEnumerable() .Select(row => new { A = row.A, B = row.B, C = (decimal)row.A * (decimal)row.B, });
Meaning:
- From my Table, take only rows that have values such that row.A * row.B < 1000.
- From each selected row, select the values from columns A and B.
- Transfer those two values to local memory (= AsEnumerable),
- for every transferred row create a new object with three properties:
- A and B have the transferred values.
- C gets the the product of the decimal values of transferred A and B
其他推荐答案
You can avoid AsEnumerable() explaining to Entity how many fractional digits you want.
var list = (from row in model.Table where ((decimal)row.A) * row.B < 1000 select new { A = row.A, B = row.B , C = (((decimal)((int)row.A)*100))/100) * row.B} ).ToList();