簡體   English   中英

實體框架SqlQuery可空字段

[英]Entity Framework SqlQuery Nullable Fields

我正在使用Entity Framework SqlQuery來獲取數據。

這是代碼:

Context.Database.SqlQuery<MyModel>("exec dbo.MySP @StartDate, @EndDate", Params.ToArray()).ToListAsync();

MyModel

public class MyModel
{
    public int? Code{ get; set; }
    public string Name{ get; set; }
    public DateTime? InsertDate { get; set; }
}

問題是當我的存儲過程結果中有一些Null列時,可空列在所有行中都變為Null 但是,當我刪除存儲過程中的那些Null列時,一切正常。

更新 :這是存儲過程

ALTER PROCEDURE [dbo].[MySP] 
    @StartDate DATETIME = NULL,
    @EndDate DATETIME = NULL
AS
BEGIN
    CREATE TABLE #LastUpdates (Code INT, InsertDate DATETIME)

    SET NOCOUNT ON;

    INSERT INTO #LastUpdates 
        SELECT
            StoreCode,
            MAX(InsertDate)
        FROM 
            [dbo].[History]
        WHERE 
            (@StartDate IS NULL OR DATEDIFF(DAY, InsertDate, @StartDate) <= 0 )
            AND (@EndDate IS NULL OR DATEDIFF(DAY, InsertDate, @EndDate) >= 1)
        GROUP BY 
            StoreCode

    SELECT DISTINCT
        store.Name as Name,
        store.Code as Code,
        Updates.InsertDate AS InsertDate
    FROM 
        #LastUpdates AS Updates 
    RIGHT JOIN 
        [Stores] AS store ON Updates.Code = store.Code
    WHERE 
        store.IsDeleted = 0

    DROP TABLE #LastUpdates 
END

您的過程需要從模型(相同名稱)返回所有屬性。 如果過程返回任何其他字段,並且您的模型期望它們,您將得到錯誤。

該查詢返回歷史記錄中的所有行,並根據條件在商店中右連接。 如果商店中沒有記錄匹配,則歷史記錄中的記錄仍包含在記錄集中。 您可能需要INNER JOIN。

似乎EF(至少在某一點)返回了空行。 因此,而不是選擇*,您應該顯式命名列並確保PK(或其他列)在前。

注意:我認為幾乎總是可以避免RIGHT JOIN; 使用LEFT JOIN查詢更容易閱讀和理解。

WHERE (@StartDate IS NULL OR DATEDIFF(DAY,InsertDate,@StartDate) <= 0 )
   AND (@EndDate IS NULL OR DATEDIFF(DAY,InsertDate,@EndDate) >= 1)

當它們為null時,將忽略它們。 但是,這仍然無法處理null InsertDates 對於null InsertDates DATEDIFF將返回null。

如果您希望返回所有空的InsertDates,則需要在查詢的其余部分添加(InsertDate is null) OR

WHERE (InsertDate is null) OR ((@StartDate IS NULL OR DATEDIFF(DAY,InsertDate,@StartDate) <= 0 )
   AND (@EndDate IS NULL OR DATEDIFF(DAY,InsertDate,@EndDate) >= 1))

出於性能原因,您可能還需要考慮使用普通的日期比較語法替換DATEDIFF InsertDate >= @StartDate將更快,尤其是在InsertDate有索引的情況下。 我還相信,這種語法可以使您更清楚地知道,您是在這些參數日期之間尋找InsertDates還是使用內置語法between語法將其轉換為> =&<=語法。

在添加SP SQL和回答問題之前:

如果沒有基本的sql,我們會在幫助您方面有點盲目,我們也需要更多信息。 我問了幾個問題(上面的問題評論中),這些問題可以幫助我們更清楚地理解:

除了:

我假設你正在做一個范圍/對之間InsertDate@StartDate@EndDate 由於這些參數都傳遞日期,因此,如果您InsertDate between @StartDate and @EndDate InsertDate >= @StartDateInsertDate between @StartDate and @EndDate類的InsertDate >= @StartDate語法/語法,則將永遠找不到null InsertDate between @StartDate and @EndDate因為NULL永遠不會等於日期,只有當@StartDate@EndDate為NULL。

如果您希望返回所有空的InsertDates則必須在查詢中添加以下內容:

select field1,field2 from table1
where (InsertDate is null) or (InsertDate >= @StartDate and InsertDate <= @EndDate)

如果@StartDate@EndDate為null,並且您希望這表示忽略該參數,則您必須查找重寫存儲過程中的基礎SQL,以處理不僅僅是InsertDate >= @StartDate

它看起來必須更像(@StartDate is null or InsertDate >= @StartDate)

@EndDate參數必須執行相同的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM