![](/img/trans.png)
[英].NET Core DateTime doesn't correctly insert/update DateTime column in SQL Server
[英]How to insert and update SQL Server DateTime in a date column using Entity Framework Core in .NET Core
我有一個包含LastUpdateOn
列的表,每當我在表中執行插入或更新操作時,我想在此列中保留 SQL Server 當前日期和時間(使用GETDATE()
)。
在 ADO.NET 中,我們曾經在插入/更新語句中調用GETDATE()
函數,但是我們如何使用 Entity Framework Core 來實現相同的功能呢?
存儲 SQL Server 日期時間的原因是我們不想將應用程序服務器日期時間存儲在 LastUpdateOn 列中,因為應用程序將從不同的服務器上運行,並且它們的時鍾可能不同步,因此我們希望存儲所有地方的公共時間(應用服務器)。
我有兩個快速解決方案:
簡單地將值作為默認值設置為該列上的 GetDate() 並在插入或更新時將 null 傳遞給 EF;
創建一個在插入/更新之前調用 GetDate() 的函數並將其用作值;
編輯:
因此,當我遠離存儲過程(我經常使用“GetDate()”或“CURRENT_TIMESTAMP”)......我接受了 c#/middleware 層。
我做了一個“空檢查”並將其設置在 c# 代碼中(在實體框架數據層代碼中)
下面顯示日期時間。 DateTime.MinValue 的意思是“有人沒有明確設置它”。
myEntityFrameworkEntity.InsertDate = parameterInsertDateValue == DateTime.MinValue ? DateTime.Now : parameterInsertDateValue;
還有其他變化,但想法是一樣的。 “調用者”是否明確設置了屬性,或者他們沒有設置它,讓我代表他們寫一個值。
現在,有時我不在乎調用者設置了什么。 如果它是 LastUpdatedDate ,您也可以“強制它”(始終將其設置為 DateTime.Now)......
// i don't care what the parameters are, i always update it in this layer
myEntityFrameworkEntity.LastUpdatedDate = DateTime.Now;
此外,而不是直接使用 DateTime(.Now) ......我使用這個:
https://github.com/vfabing/Chronos.Net
您“注入”了一個可以為單元測試模擬的 DateTime-PROVIDER ..。
這是一個更完整的示例來顯示我的 EF 代碼(對於需要“斷開連接”實體的 Rest-Services)。
public const int ExpectedAddSingleOrUpdateSingleOrDeleteSingleSaveChangesAsyncRowCount = 1;
public async Task<EmployeeEfEntity> UpdateAsync(
EmployeeEfEntity inputEmployee,
CancellationToken token)
{
int saveChangesAsyncValue = 0;
/* find the object in the db-context using the object surrogate-primary-key (since this is an update) */
EmployeeEfEntity foundEntity =
await this.entityDbContext.EmployeeEfEntitys.FirstOrDefaultAsync(
item => item.EmployeeEfEntityKey == inputEmployee.EmployeeEfEntityKey,
token);
if (null != foundEntity)
{
/* update the found-entity with the properties of the input object */
/* the "normal" properties of the employee */
foundEntity.EmployeeBadgeNumber = inputEmployee.EmployeeBadgeNumber;
/* if the insert-date was explicit, use it, otherwise default to date-time.now */
foundEntity.InsertDate = inputEmployee.InsertDate == DateTime.MinValue ? DateTime.Now : inputEmployee.InsertDate;
/* we do not care about the input parameters, we always set it to "now" */
foundEntity.LastUpdated = inputEmployee.LastUpdated == DateTime.Now;
this.entityDbContext.Entry(foundEntity).State = EntityState.Modified;
saveChangesAsyncValue = await this.entityDbContext.SaveChangesAsync(token);
if (ExpectedAddSingleOrUpdateSingleOrDeleteSingleSaveChangesAsyncRowCount != saveChangesAsyncValue)
{
throw new ArgumentOutOfRangeException(
string.Format(ErrorMsgExpectedSaveChangesAsyncRowCount, saveChangesAsyncValue),
(Exception)null);
}
}
else
{
ArgumentOutOfRangeException argEx = new ArgumentOutOfRangeException(
string.Format(ErrorMsgPrimaryEntityNotFound, inputEmployee.EmployeeEfEntityKey),
(Exception)null);
this.logger.LogError(argEx);
}
return foundEntity;
}
我的代碼實際上使用了 Chronos.Net(注入)日期時間提供程序,但我刪除了它以使代碼更簡單地回答這個問題。
由於您使用的是實體框架,該框架旨在允許更多地在 C# 中處理數據庫使用,因此我將只使用 DateTime.Now(如果您想要 UTC 時間,則使用 DateTime.UtcNow)。
每次輸入/更新記錄時,將LastUpdateOn
設置為DateTime.Now
或DateTime.Utc.Now
。
如果你真的想使用 SQL server 的GETDATE()
方法,那么編寫一個存儲過程,它接受一個整數(要更新的記錄的 id),並使用它來將具有指定 id 的字段的LastUpdateOn
設置為GETDATE()
.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.