[英]Entity Framework 6 related entity where datetime clause doesn't translate to SQL
如何在不訪問數據庫上下文的情況下將日期過濾器放入生成的SQL查詢中?
EF進行一些非常昂貴的查詢。 我不會將結果強制轉換為IEnumerable或將其用作IEnumerable,所以我希望EF能夠進行有效的查詢。 我希望它使用開始和停止時間來過濾SQL中的結果。
EF翻譯了以下內容
context.Channels
.First(ch => ch.Channel_ID == id)
.ChannelValues
.Where(cv => start < cv.ValueTime && cv.ValueTime <= stop);
成
SELECT TOP (1)
[Extent1].[Channel_ID] AS [Channel_ID],
[Extent1].[ChannelType_ID] AS [ChannelType_ID],
[Extent1].[Name] AS [Name],
FROM [dbo].[Channel] AS [Extent1]
WHERE [Extent1].[Channel_ID] = @p__linq__0
p__linq__0: '1' (Type = Int32, IsNullable = false)
SELECT
[Extent1].[Channel_ID] AS [Channel_ID],
[Extent1].[ValueTime] AS [ValueTime],
[Extent1].[Value] AS [Value]
FROM [dbo].[ChannelValue] AS [Extent1]
WHERE [Extent1].[Channel_ID] = @EntityKeyValue1
EntityKeyValue1: '1' (Type = Int32, IsNullable = false)
我很滿意的第一個SQL查詢,但是第二個應該創建類似於以下內容的查詢
context.ChannelValues
.Where(cv => cv.Channel_ID == id && start < cv.ValueTime && cv.ValueTime <= stop);
它導致
SELECT
[Extent1].[Channel_ID] AS [Channel_ID],
[Extent1].[ValueTime] AS [ValueTime],
[Extent1].[Value] AS [Value]
FROM [dbo].[ChannelValue] AS [Extent1]
WHERE ([Extent1].[Channel_ID] = @p__linq__0) AND (@p__linq__1 < [Extent1].[ValueTime]) AND ([Extent1].[ValueTime] <= @p__linq__2)
p__linq__0: '1' (Type = Int32, IsNullable = false)
p__linq__1: '7/1/2018 12:00:00 AM' (Type = DateTime2, IsNullable = false)
p__linq__2: '7/23/2018 11:45:00 AM' (Type = DateTime2, IsNullable = false
在我實際需要的地方,我無權訪問DatabaseContext。
我認為查詢的第二部分根本沒有傳遞給SQL。
這告訴SQL返回Channel_ID等於id的所有ChannelValues。
context.Channels
.First(ch => ch.Channel_ID == id)
.ChannelValues
然后在內存中執行第二個where子句。
.Where(cv => start < cv.ValueTime && cv.ValueTime <= stop);
要在數據庫中執行所有這些操作,您將需要執行以下操作:
context.Channels
.Where(ch => ch.Channel_ID == id)
.SelectMany(x => x.ChannelValues)
.Where(cv => start < cv.ValueTime && cv.ValueTime <= stop)
雖然我不知道這是否回答您是否在不訪問數據庫上下文的情況下如何做到這一點
“ EF進行一些非常昂貴的查詢”,如果您知道有什么不好的地方,但仍然以這種方式(不是EF錯誤)進行操作,則可以控制如何使用具有局限性的框架*。
您可以完全按照自己的方式來做。
即,如果您使用原始sql執行此操作,您將如何做。
然后只需在EF中執行相同操作即可。
var channel = context.Channels.First(x=> x.Channel_ID == id)
channel.ChannelValues = context.ChannelValues.Where(x => x.Channel_ID == id
&& start < x.ValueTime
&& x.ValueTime <= stop
).ToList();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.