为什么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 需要无参数构造函数。幸运的是,它通过反射找到了它,所以你可以将那个构造函数设为私有。