为什么Linq/Lambda中有符号负数(十进制)要转为无符号?
Why are signed negative numbers (decimal) Converted into unsigned in Linq/Lambda?
我有一个名为 Transactions 的 table 数据如下:
SELECT [ID]
,[DateTime]
,[AccountID]
,[Type]
,[Amount]
FROM [TestModelDb].[dbo].[Transactions]
输出:
ID DateTime AccountID Type Amount
1 2015-03-17 1 0 10.00
2 2015-03-17 3 0 20.00
3 2015-03-17 1 0 100.00
4 2015-03-18 1 1 -10.00
5 2015-03-18 3 1 -5.00
我正在使用代码优先。当我做一个简单的查询时,金额列中的所有十进制数字都是无符号的:
IEnumerable<decimal> test = Transactions.Select(t => t.Amount);
foreach (decimal amount in test)
{
Debug.WriteLine("Amount: " + amount);
}
在输出框中显示为:
Amount: 10.00
Amount: 100.00
Amount: 10.00
Amount: 20.00
Amount: 5.00
为什么 linq 或 lambda 查询会掉落符号?
更新#1
交易Class:
public partial class Transaction : EntityBase
{
public Transaction()
{
DateTime = DateTime.Now;
}
/// <summary>
/// Gets or sets the date time.
/// </summary>
/// <value>The date time.</value>
public DateTime DateTime { get; set; }
/// <summary>
/// Gets or sets the account identifier.
/// </summary>
/// <value>The account identifier.</value>
public int AccountID { get; set; }
/// <summary>
/// Class Transaction.
/// </summary>
/// <summary>
/// Gets or sets the account.
/// </summary>
/// <value>The account.</value>
[ForeignKey("AccountID")]
public Account Account { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>The type.</value>
[Required]
public TransactionType Type { get; set; }
private decimal _amount;
/// <summary>
/// Gets or sets the amount.
/// </summary>
/// <value>The amount.</value>
public decimal Amount
{
get { return _amount; }
set
{
decimal temp;
if (Type == TransactionType.Withdrawal)
temp = value*-1;
else temp = value;
_amount = temp;
}
}
}
我的 DbContext:
public class TestContext : DbContext
{
public TestContext()
: base("name=TestContext")
{
}
public DbSet<Person> People { get; set; }
public DbSet<Account> Accounts { get; set; }
public DbSet<Transaction> Transactions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
我猜你的交易类型被标记为取款,所以你的代码在这里将数字从负数翻转为正数:
if (Type == TransactionType.Withdrawal)
temp = value*-1;
Entity Framework 在每个 属性 上使用 setter 当它从数据库调用中混合对象时。换句话说,当它构建对象时,它将 Amount
设置为 -10,但由于它是一个提款,这段代码(正如 Robert 指出的那样)将值翻转回正值:
if (Type == TransactionType.Withdrawal)
temp = value*-1;
尝试将其更改为:
if (Type == TransactionType.Withdrawal && value > 0)
temp = value*-1;
此外,正如罗伯特评论的那样,var t = new Transaction(); t.TransactionType=Withdrawl; t.Amount=50;
和 var t = new Transaction(); t.Amount=50;t.TransactionType=Withdrawl;
给出不同的结果是非常危险的。
您可能应该使 Transaction
类型不可变,或者至少在构造函数中需要该类型。如果这样做,请记住 EF 需要无参数构造函数。幸运的是,它通过反射找到了它,所以你可以将那个构造函数设为私有。
我有一个名为 Transactions 的 table 数据如下:
SELECT [ID]
,[DateTime]
,[AccountID]
,[Type]
,[Amount]
FROM [TestModelDb].[dbo].[Transactions]
输出:
ID DateTime AccountID Type Amount
1 2015-03-17 1 0 10.00
2 2015-03-17 3 0 20.00
3 2015-03-17 1 0 100.00
4 2015-03-18 1 1 -10.00
5 2015-03-18 3 1 -5.00
我正在使用代码优先。当我做一个简单的查询时,金额列中的所有十进制数字都是无符号的:
IEnumerable<decimal> test = Transactions.Select(t => t.Amount);
foreach (decimal amount in test)
{
Debug.WriteLine("Amount: " + amount);
}
在输出框中显示为:
Amount: 10.00
Amount: 100.00
Amount: 10.00
Amount: 20.00
Amount: 5.00
为什么 linq 或 lambda 查询会掉落符号?
更新#1
交易Class:
public partial class Transaction : EntityBase
{
public Transaction()
{
DateTime = DateTime.Now;
}
/// <summary>
/// Gets or sets the date time.
/// </summary>
/// <value>The date time.</value>
public DateTime DateTime { get; set; }
/// <summary>
/// Gets or sets the account identifier.
/// </summary>
/// <value>The account identifier.</value>
public int AccountID { get; set; }
/// <summary>
/// Class Transaction.
/// </summary>
/// <summary>
/// Gets or sets the account.
/// </summary>
/// <value>The account.</value>
[ForeignKey("AccountID")]
public Account Account { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>The type.</value>
[Required]
public TransactionType Type { get; set; }
private decimal _amount;
/// <summary>
/// Gets or sets the amount.
/// </summary>
/// <value>The amount.</value>
public decimal Amount
{
get { return _amount; }
set
{
decimal temp;
if (Type == TransactionType.Withdrawal)
temp = value*-1;
else temp = value;
_amount = temp;
}
}
}
我的 DbContext:
public class TestContext : DbContext
{
public TestContext()
: base("name=TestContext")
{
}
public DbSet<Person> People { get; set; }
public DbSet<Account> Accounts { get; set; }
public DbSet<Transaction> Transactions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
我猜你的交易类型被标记为取款,所以你的代码在这里将数字从负数翻转为正数:
if (Type == TransactionType.Withdrawal)
temp = value*-1;
Entity Framework 在每个 属性 上使用 setter 当它从数据库调用中混合对象时。换句话说,当它构建对象时,它将 Amount
设置为 -10,但由于它是一个提款,这段代码(正如 Robert 指出的那样)将值翻转回正值:
if (Type == TransactionType.Withdrawal)
temp = value*-1;
尝试将其更改为:
if (Type == TransactionType.Withdrawal && value > 0)
temp = value*-1;
此外,正如罗伯特评论的那样,var t = new Transaction(); t.TransactionType=Withdrawl; t.Amount=50;
和 var t = new Transaction(); t.Amount=50;t.TransactionType=Withdrawl;
给出不同的结果是非常危险的。
您可能应该使 Transaction
类型不可变,或者至少在构造函数中需要该类型。如果这样做,请记住 EF 需要无参数构造函数。幸运的是,它通过反射找到了它,所以你可以将那个构造函数设为私有。