2017-04-14 9 views
0

で通貨換算複雑さと優れた請求書を取得し、私はそれが様々な性質を持っている、エンティティはInvoice.csと呼ばれる持っているが、ここでは質問に対する心配なものです:私のEntity FrameworkのアプリケーションでLINQ

public class Invoice : IEntity 
{ 
    public int Id { get; set; } 
    public decimal Amount { get; set; } 
    public DateTime Date { get; set; } 
    public int OrderId { get; set; } 
    public virtual ICollection<Payment> Payments { get; set; } 
} 

未処理のすべての請求書の一覧を取得するためにデータベースにクエリを実行しようとしています。請求書に対して支払いの合計請求書金額より小さい

場合は、請求書が優れです:優れた請求書は次のとおりです。

請求書は現在、次のようになります私のLINQクエリに優れているか、いない場合、私はワークアウトにこだわっている:

var outstandingInvoices = from inv in _context.Invoices 
    where !inv.IsDeleted && inv.Date >= startDate && inv.Date <= endDate 
    select inv; 

startDateendDateは、結果をフィルタリングするために渡されたパラメータです。

これと別の複雑さは、支払いの仕方に関係します。支払いはRMB(中国通貨)またはGBP(英国通貨)で行うことができ、私が生成しているレポートでは、すべてをGBPとして表示します。

だから私は何とかあまりにもこのロジックを追加する必要があります。

// loop through payments for each invoice, and add payment 
// amount to a local variable called total 
if (payment.Currency == Currency.Gbp) 
{ 
    total += payment.Amount; 
} else 
{ 
    total += payment.Amount/(decimal)payment.ConversionRate; 
} 

Payment.csエンティティが懸念されるこれら2つのプロパティがあります

public class PaymentViewModel 
{ 
    public int Id { get; set; } 
    [Required] 
    public decimal Amount { get; set; } 
    [Required] 
    [Display(Name = "Payment Currency")] 
    public Currency Currency { get; set; } 
    [Display(Name = "Conversion Rate")] 
    public float ConversionRate { get; set; } 
} 
+0

請求額があまりにもGBPである、またはそれは任意の通貨になることができますか? –

+0

Gbpにあるレコードの場合、 'CoversionRate' 1ですか? –

+0

Yep @RobertMcKee – Ciwan

答えて

1

浮動小数点の違いのために訴えます。データベースプロバイダによっては、キャストを10進数から浮動小数点数に強制することができます(そうでない場合もあります)。もちろん、あなたは本当に近いですが、まったく同じではない支払いの問題があります。金額が1 GBPの場合、金額/ CoversionRateが0.999999999999999999999999999 GBPの場合はどうなりますか?技術的には完全には支払われていません。

最終的には、変換率も浮動小数点ではなく10進数である必要がありますが、精度はソースによって異なります。小数点以下5桁または7桁まで正確ですか?

また
var outstanding = _context.Invoices 
    .Where(x=>x.Date >= startDate) 
    .Where(x=>x.Date <= endDate) 
    .Where(x=>!x.IsDeleted) 
    .Where(x=>x.Payments.Sum(p=>(float)p.Amount/p.ConversionRate) < x.Amount); 

支払った合計が1 GBP内であれば:

var outstanding = _context.Invoices 
    .Where(x=>x.Date >= startDate) 
    .Where(x=>x.Date <= endDate) 
    .Where(x=>!x.IsDeleted) 
    .Where(x=>x.Payments.Sum(p=>(float)p.Amount/p.ConversionRate) - x.Amount < 1); 
1

をあなたは場合の支払額を調整するために三項演算子を使用することができますGBPではありません:

var outstandingInvoices = 
     from inv in _context.Invoices 
     let totalPayment = inv.Payments.Sum(p => 
       p.Currency == Currency.Gbp ? p.Amount : p.Amount/p.ConversionRate) 
     where !inv.IsDeleted 
      && inv.Date >= startDate && inv.Date <= endDate     
      && totalPayment < inv.Amount 
     select inv; 
+0

キャストが発生すると、次のエラーが発生します。 「必要な精度と位取り情報が推測できないため、LINQ to Entitiesクエリでは小数へのキャストはサポートされていません」 – Ciwan

+0

@シワン私のコードにキャストはありません。どこに追加しましたか? –

+0

分割が発生する場合、ConversionRateは浮動小数点型です – Ciwan

関連する問題