[英]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 >= @StartDate
或InsertDate 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.