Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linq 组合查询结果的最有效方法_Linq_Entity Framework - Fatal编程技术网

Linq 组合查询结果的最有效方法

Linq 组合查询结果的最有效方法,linq,entity-framework,Linq,Entity Framework,这个问题有些探索性,因为我决定在尝试实施之前征求意见/建议,以期更及时地获得结果。我有一个数据库,以1分钟的格式存储商品和股票的日内数据。这背后的基本原理是,如果我有1分钟的条形图,我可以创建我想要的任何时间序列条形图(即5分钟、15分钟、60分钟等) 我想走这样的路线,例如,在一个15分钟的图表上,我将简单地迭代给定符号的整个结果子集,查找时间戳为:01,:16,:31:46的行,开始捕获打开、关闭、最大高、最小低和累积卷,并从合并中创建新的数据点。问题是,对于商品,尤其是24小时交易的商品,

这个问题有些探索性,因为我决定在尝试实施之前征求意见/建议,以期更及时地获得结果。我有一个数据库,以1分钟的格式存储商品和股票的日内数据。这背后的基本原理是,如果我有1分钟的条形图,我可以创建我想要的任何时间序列条形图(即5分钟、15分钟、60分钟等)

我想走这样的路线,例如,在一个15分钟的图表上,我将简单地迭代给定符号的整个结果子集,查找时间戳为:01,:16,:31:46的行,开始捕获打开、关闭、最大高、最小低和累积卷,并从合并中创建新的数据点。问题是,对于商品,尤其是24小时交易的商品,并非每分钟都有一个小节,因此可能存在一种情况,即给定符号没有:16小节或:31小节。这可能会影响正确获取条形图数据的整个过程。这也消除了一次只抓取15根杆并捕获打开、关闭、最大和最小音量以及累积音量的可能性。(当然,该表包含符号、日期时间、打开、高、低、关闭和音量)

为了使上述任何一个都能工作,我必须每天晚上“修复”数据库,检查缺少的条,并复制前面的条,为缺少的行创建条。这不是首选的方法,但必要时我会让它发生

我正在寻找一条正确的道路上的任何指导,无论是从过去的经验中,还是从阅读关于这个问题的文章中

更新: 下面是我提出的代码,它可以工作,但是有点慢,从数据库表中的1分钟数据创建2个月的30分钟条形图大约需要30秒

Partial Class testintracharts
Inherits Page
<WebMethod>
Public Shared Function GetBars(ByVal symbol As String, ByVal seriesInterval As Integer) As List(Of ArrayList)

    Dim barsList As New List(Of ArrayList)
    'replace with TD model
    Using ctx As New BATLEntities()

        ctx.Configuration.AutoDetectChangesEnabled = False

        'get all days for a given symbol, ordered from oldest to newest
        Dim dateList As List(Of DateTime) = GetDistinctDates(ctx, symbol, seriesInterval).ToList()

        'cache data series toa list for the given symbol
        Dim seriesList As List(Of tsintrachart) = GetSymbolSeries(ctx, symbol)

        If Not dateList Is Nothing And dateList.Any() Then
            For Each seriesDate As DateTime In dateList
                Dim curTime As TimeSpan = New TimeSpan(0, 1, 0)
                Dim maxTime As TimeSpan = New TimeSpan(24, 0, 0)

                'loop through the data series for the given day
                'series start at 00:01:00
                'series ends at 00:00:00 (next day)

                While curTime < maxTime
                    Dim seriesMax As TimeSpan = curTime.Add(New TimeSpan(0, seriesInterval - 1, 0))

                    'get the data chunk based on series interval
                    'special condition when seriesmax reaches 24:00:00, in TimeSpan this becomes 1.00:00:00 (SQL doesn't like this)
                    'query needs to incorporate 00:00:00 of next day as the last entry for this time series

                    Dim data As List(Of tsintrachart) = Nothing
                    If TimeSpan.Compare(seriesMax, maxTime) = 0 Then
                        Dim nextSeriesDate As DateTime = seriesDate.AddDays(1)
                        data = GetDataSeries(seriesList, seriesDate, curTime, nextSeriesDate, New TimeSpan(0, 0, 0))
                    Else
                        data = GetDataSeries(seriesList, seriesDate, curTime, seriesDate, seriesMax)
                    End If

                    If Not data Is Nothing And data.Any() Then

                        Dim lastbarnum As Integer = data.Count - 1
                        Dim intradayDatum As New ArrayList()
                        With intradayDatum
                            .Add(DateTimeToUnixTimestamp(seriesDate.Add(seriesMax))) 'date
                            .Add(data(0).Open)
                            '.Add((From d In data Where TimeSpan.Compare(d.Time, curTime) = 0 Select d.Open).FirstOrDefault()) 'open
                            .Add((From d In data Select d.High).Max()) 'high
                            .Add((From d In data Select d.Low).Min()) 'low 
                            .Add(data(lastbarnum).Close)
                            '.Add((From d In data Where TimeSpan.Compare(d.Time, seriesMax) = 0 Select d.Close).FirstOrDefault()) 'close or last sale
                            .Add((From d In data Select d.Volume).Sum()) 'volume 
                        End With
                        barsList.Add(intradayDatum)

                    End If

                    'update current series start time, move to next series chunk
                    curTime = curTime.Add(New TimeSpan(0, seriesInterval, 0))
                End While

            Next
        End If
    End Using

    Return barsList
End Function

Private Shared Function GetDataSeries(ByRef list As List(Of tsintrachart), ByVal startDate As DateTime, ByVal startSpan As TimeSpan, ByVal endDate As DateTime, ByVal endSpan As TimeSpan) As List(Of tsintrachart)
    'LINQ, where symbol/time>=startRange/time<=endRange

    Dim series = From data In list
                 Where (TimeSpan.Compare(data.Time, startSpan) >= 0 AndAlso data.Date = startDate) _
                 And (TimeSpan.Compare(data.Time, endSpan) <= 0 AndAlso data.Date = endDate)
                Select data

    Return series.ToList()
End Function

Private Shared Function GetSymbolSeries(ByRef ctx As BATLEntities, ByVal symbol As String) As List(Of tsintrachart)
    Dim series = From data In ctx.tsintracharts
                 Where (data.Symbol = symbol)
                Select data

    Return series.ToList()
End Function

Private Shared Function GetDistinctDates(ByRef ctx As BATLEntities, ByVal symbol As String, ByVal interval As Integer) As IQueryable(Of DateTime)
    Dim numDates As Integer = TakeValue(interval)
    Dim dates = (From data In ctx.tsintracharts
                Where data.Symbol = symbol
                Select data.Date
                Order By [Date]).Distinct().Take(numDates)

    Return dates
End Function
Private Shared Function TakeValue(ByVal interval As Integer) As Integer
    Select Case interval
       Case 0 To 15
            Return 1440
        Case 16 To 30
            Return 720
        Case 31 To 60
            Return 528
        Case Else
            Return 400
    End Select
End Function
End Class
部分类测试程序
继承页面
公共共享函数GetBars(ByVal符号作为字符串,ByVal序列Interval作为整数)作为列表(ArrayList的)
Dim barsList作为新列表(ArrayList的)
"代之以TD模式"
使用ctx作为新的BatLenties()
ctx.Configuration.AutoDetectChangesEnabled=False
'获取给定符号的所有天数,从最早到最新排序
Dim dateList作为列表(日期时间)=GetDistinctDates(ctx、symbol、seriesInterval)。ToList()
'将数据系列缓存到给定符号的列表
Dim系列列表为列表(tsintrachart)=GetSymbolSeries(ctx,symbol)
如果dateList不是Nothing,则dateList.Any()为Nothing
对于每个系列,日期作为日期列表中的日期时间
Dim curTime As TimeSpan=新的时间跨度(0,1,0)
Dim maxTime As TimeSpan=新的时间跨度(24,0,0)
'循环浏览给定日期的数据系列
'系列从00:01:00开始
'系列在00:00:00(第二天)结束
而curTime=startRange/time=0,并且还包含数据。Date=startDate)_

和(TimeSpan.Compare(data.Time,endSpan)您可以创建一个包含所有可能的1min时间点的表。然后您可以
外部连接到该表,以使服务器填补任何空白。该表如下所示:

CREATE TABLE TimePoints (
 DateTime DATETIME2(0) PRIMARY KEY
)
您需要填写几十年的数据。要查询,您需要加入:

SELECT *
FROM TimePoints
LEFT JOIN myOtherTable ON ...
WHERE TimePoints.DateTime >= (nowMinus15min) AND TimePoints.DateTime <= now
选择*
从时间点
在…上左键连接myOtherTable。。。

其中TimePoints.DateTime>=(现在小于15分钟)和TimePoints.DateTime,除非我重新读取不正确