Ich bin ein Subsystem von NHibernate-Entity Framework Portierung und wollen den besten Weg, um Port die folgende Abfrage EF zu sehen.Subquery mit Entity Framework
var date = DateTime.Now; // It can be any day
AccountBalanceByDate abbd = null;
var lastBalanceDateByAccountQuery = QueryOver.Of<AccountBalanceByDate>()
.Where(x => x.AccountId == abbd.AccountId && x.Date < date)
.Select(Projections.Max<AccountBalanceByDate>(x => x.Date));
var lastBalances = session.QueryOver<AccountBalanceByDate>(() => abbd)
.WithSubquery.WhereProperty(x => x.Date).Eq(lastBalanceDateByAccountQuery)
.List();
Der Kontostand Klasse:
public class AccountBalanceByDate
{
public virtual int Id { get; set; }
public virtual int AccountId { get; set; }
public virtual DateTime Date { get; set; }
public virtual decimal Balance { get; set; }
}
Der Tisch ist:
CREATE TABLE [dbo].[AccountBalanceByDate]
(
[Id] int NOT NULL,
[AccountId] int NOT NULL,
[Date] [datetime] NOT NULL,
[Balance] [decimal](19, 5) NOT NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)
)
Ein Beispieldaten (numerische IDs für ein besseres Verständnis verwenden):
Id | Date | Account | Balance
------------------------------------
1 | 2014-02-01 | 101 | 1390.00000
2 | 2014-02-01 | 102 | 1360.00000
3 | 2014-02-01 | 103 | 1630.00000
4 | 2014-02-02 | 102 | 1370.00000
5 | 2014-02-02 | 103 | 1700.00000
6 | 2014-02-03 | 101 | 1490.00000
7 | 2014-02-03 | 103 | 1760.00000
8 | 2014-02-04 | 101 | 1530.00000
9 | 2014-02-04 | 102 | 1540.00000
Die AccountBalanceByDate Entität den Kontostand an einem bestimmten Tag halten. Wenn ein Tag keine Transaktion hat, hat dieser Tag keine AccountBalanceByDate und wir sollten nach den vorherigen Tagen suchen, um den Kontostand für dieses Konto zu sehen.
Wenn ich mit dem Datum abfragen 2014.02.01 sollte ich:
No results
Wenn ich mit dem Datum abfragen 2014.02.02 sollte ich:
1 | 2014-02-01 | 101 | 1390.00000
2 | 2014-02-01 | 102 | 1360.00000
3 | 2014-02-01 | 103 | 1630.00000
Wenn ich mit dem Datum 2014.02.03 Abfrage soll ich:
1 | 2014-02-01 | 101 | 1390.00000
4 | 2014-02-02 | 102 | 1370.00000
5 | 2014-02-02 | 103 | 1700.00000
Wenn ich mit dem Datum abfragen 2014.02.04 sollte ich:
4 | 2014-02-02 | 102 | 1370.00000
6 | 2014-02-03 | 101 | 1490.00000
7 | 2014-02-03 | 103 | 1760.00000
Wenn ich mit dem Datum abfragen 2014.02.05 Ich sollte erhalten:
7 | 2014-02-03 | 103 | 1760.00000
8 | 2014-02-04 | 101 | 1530.00000
9 | 2014-02-04 | 102 | 1540.00000
Ich kann dies in Entity Framework mit Raw SQL, aber es ist nicht das Ideal.
using (var context = new DbContext())
{
var lastBalances = context.AccountBalanceByDate.SqlQuery(
@"SELECT
*
FROM
[AccountBalanceByDate] AB
WHERE
DATE = (
SELECT
MAX(Date)
FROM
[AccountBalanceByDate]
WHERE
AccountId = AB.AccountId AND DATE < @p0
)", date).ToList();
}
Es ist bevorzugt, nur ein einziges Mal in der Datenbank zu gehen, wie in NHibernate und roher SQL, aber mit nur Linq ist es möglich?
UPDATE:
Feste Ergebnisse in der Frage.
SQL die Beispielabfrage auf GIST zeigt: https://gist.github.com/LawfulHacker/275ec363070f2513b887
Entity Framework Probe auf GIST: https://gist.github.com/LawfulHacker/9f7bd31a21363ee0b646
Ihre eigene SQL-Abfrage, die Sie in Ihrer Frage gab nicht die Ergebnisse produzieren! Abfrage für 2014-02-01 gibt nichts zurück! FIX deine Anfrage zuerst. –
@AgentShark, bitte beachten Sie, dass ich eine Unterabfrage habe, die auf die oberste Tabelle verweist, und zwar für jede Zeile. Dann erhält es für jede Zeile seine Konto-ID und erhält das maximale Datum. Es gibt mir alle Ergebnisse im maximalen Datum jedes Kontos zurück, das maximale Datum kann für jedes Konto unterschiedlich sein. Es ist der Haken, meine Stichprobe ist korrekt, ich habe es erneut überprüft, als Sie darauf hingewiesen haben, dass es falsch war. – LawfulHacker
Ich bekomme, was Sie versuchen, aber ich habe Ihre genauen Daten in SQL Server 2008 eingegeben und Ihre Abfrage ausgeführt. "2014-02-01" gibt nichts zurück. '2014-02-02' gibt Ids 3,2,1 zurück. "2014-02-03" zurück Ids 5,4,1. '2014-02-04' gibt Ids 7,4,6 zurück. –