簡體   English   中英

EF6:在哪里創建存儲過程?

[英]EF6: where to create stored procedures?

我正在使用Entity Framework 6 Code First。 要使用我的數據庫,我需要一個存儲過程。 每當創建數據庫時,都需要創建此存儲過程。

編輯:存儲過程的原因寫在這篇文章的結尾。

從Stackoverflow我知道如何創建存儲過程以及如何調用它。 我的問題是在哪里創建它?

我的第一個直覺是在DbContext.OnModelCreating中 每當創建模型時,都會調用此函數。 在此功能中,您將告訴模型構建者模型應該是什么樣。

,在此功能中,我還不能使用DbContext。 有一些功能可以覆蓋“插入/更新/刪除”過程,但是我需要一個不同的過程。

我考慮在DropCreateDataBaseIfModelChanges的Seed函數中添加該函數,但這將禁止我的DbContext用戶使用其所需的數據為數據庫播種。

DbMigrations似乎是為了將現有數據庫遷移到新數據庫而開發的。 創建數據庫的第一個版本時不使用。

那么在哪里創建存儲過程呢?


編輯。 我需要存儲過程的原因如下

我的服務收到有關客戶今天花錢購物的通知。 我需要記住每個客戶的當天總計。

  • 如果客戶在date上還沒有花費任何東西, 也就是說 ,如果不存在帶有(customerId,date)的記錄,則插入一條帶有花費值的記錄
  • 如果客戶已經在datae上花了一些也就是說 ,如果已經存在帶有(customerId,date)的記錄,則將花費的值添加到記錄中的值

像這樣:

public void InsertOrAdd(int customerId, DateTime date, decimal value)
{
    using (var dbContext = CreateContext())
    {
        var retrievedRecord = dbContext.Find(...)
        if (retrievedRecord == null)
        {
            InsertRecord(customerId, date, value);
        }
        else
        {
            retrievedRecord.Value += value;
            dbContext.SaveChanges();
        }
    }
}

問題是在“查找”之后,其他人可能已經插入了一條記錄。 在那種情況下,我應該添加值。 而是會有兩個記錄。 或者在我處理現有記錄並添加值時,其他人可能會處理相同的現有記錄。 因此,值的添加應在數據庫內部使用如下語句完成:

update [CustomerSpends]
Set [SpentValue] = [SpentValue] + @Value
Where [CustomerId] = @CustomerId and [SpentDate] = @SpentDate

第二次編輯正如Ivan Yuriev *已經提到的,可以使用事務來解決上述問題。 但是我仍然會遇到增加支出的問題。

如果這是一個三步驟的過程(如Ivan所建議的那樣),則它將是:

  • 獲取現有記錄
  • 將支出值添加到記錄的總值中
  • 保存更改

這樣做的缺點是我總是需要兩次往返數據庫。 此外,我得到了一系列的客戶支出。 如果其中任何一個處理失敗,則需要回滾所有內容。 即使使用交易,也可能存在競爭條件

最高的事務隔離級別(MSDN)已讀取為已提交。

READ COMMITTED指定語句不能讀取已被其他事務修改但未提交的數據。 這樣可以防止臟讀。 數據可以被當前事務中各個語句之間的其他事務更改,從而導致不可重復的讀取或幻像數據。

當使用上面定義的三步過程時,我獲取記錄X,總花費值為5.00美元。 當我將總計增加3美元時,其他人也可以獲取記錄X,因為它尚未被修改。 另一個接收的記錄總計為$5。添加后,總值為$8。我使用SaveChanges更新值,並繼續其他記錄。 一段時間后,我提交更改。 另一個仍有$ 5記錄的進程應加$ 2,以$ 7結尾,而最終結果應為$ 10

使用事務不能阻止其他人讀取數據。 因此,獲取-添加值-更新應在一條SQL語句中完成

通過創建空白遷移並在Up方法中添加存儲過程並在Down Method中刪除該存儲過程的最佳管理方式

這將像。

1)通過在Package Manger Console上運行命令來添加空白遷移

add-migration 'SomeName' -IgnoreChanges

它將創建遷移文件

2)現在,在“向上”中添加存儲過程,在“向下”中刪除存儲過程

public partial class SomeName: DbMigration
    {
        public override void Up()
        {
            Sql(@"Add Command For StoredProcedure");

        }

        public override void Down()
        {
            Sql(@"Drop Command for Stored Procedure")
        }
    } 

添加Drop in Down方法同樣重要。

無處。 我發現代碼優先遷移非常有限,只有只有對SQL Server概念和功能缺乏深入了解的人才能使用它。

我走的路是:

  • 我維護一個主數據庫並將架構同步到架構項目。
  • 定期生成增量腳本,然后由我手動維護。
  • 我有一個庫,該庫根據擴展屬性中存儲的數據庫的版本號,根據需要應用增量腳本。

不使用遷移的原因很簡單-無論如何,您最終不得不提交太多的SQL腳本。 遷移甚至無法處理瑣碎的情況,例如正確的完全配置的索引(過濾的索引),不了解存儲過程,觸發器和視圖,無法處理分區表,無法有效地處理可能需要臨時表的數據遷移在表布局更改時存儲數據。 因為我不處理瑣碎的數據庫,所以幾乎每天都需要幾乎所有這些功能。

說出全部真相-我從來沒有找到過代碼甚至是一種有效的方法。 太容易出錯了。 更糟糕的是,db首先使用EF工具-主要是因為edmx設計器變得越來越爛,完全無法處理更新。 但是可以使用第三方編輯器,並且它們可以工作。

暫無
暫無

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

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